@openwop/openwop-conformance 2.45.10 → 2.45.12
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 +31 -0
- package/README.md +2 -2
- package/dist/lib/profiles.js +3 -1
- package/dist/spec-artifacts.lock.json +2 -2
- package/fixtures/connection-packs/connection-pack-acme-widgets-rival.json +55 -0
- package/fixtures/connection-packs/connection-pack-acme-widgets.json +29 -5
- package/fixtures.md +1 -0
- package/package.json +2 -2
- package/requirements.json +235 -24
- package/scenario-majors.json +8 -2
- package/schemas/CORPUS-STAMP.json +19 -17
- package/src/lib/major-profile.ts +17 -0
- package/src/lib/profiles.ts +3 -1
- package/src/lib/provider-registry-double.ts +70 -0
- package/src/lib/provider-registry-witness.ts +107 -0
- package/src/lib/trigger-delivery-witness.ts +340 -0
- package/src/lib/trigger-double.ts +133 -0
- package/src/scenarios/trigger-bridge-delivery.test.ts +61 -2
- package/src/scenarios/v2-advertised-path-space-served.test.ts +12 -2
- package/src/scenarios/v2-provider-conflict.test.ts +77 -17
- package/src/scenarios/v2-trigger-bridge-delivery.test.ts +136 -0
- package/src/scenarios/v2-trigger-dead-letter-read.test.ts +78 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# `@openwop/openwop-conformance` Changelog
|
|
2
2
|
|
|
3
|
+
## [2.45.12] — 2026-10-03 — RFC 0233: the provider-identity rules have a normative witness
|
|
4
|
+
|
|
5
|
+
- **`v2-provider-conflict` gains a normative-surface path (RFC 0233).** Where the host advertises `connections.providerRead` it reads `GET /connection-providers` and `GET /connection-providers/{providerId}` (`?pack=` for the qualified form). The conflict is caused operator-side by installing the `connection-pack-acme-widgets` / `-rival` fixture pair, and the registry describes the outcome. The seam path still runs where the seams are served.
|
|
6
|
+
- `openwop.requirement.0177.provider-conflict.fail-closed`: `acme-widgets` is held once by the first pack, and a `connection_provider_conflict` refusal names that holder.
|
|
7
|
+
- `openwop.requirement.0177.provider-conflict.qualified-form`: `?pack=<first>` resolves to it; `?pack=<rival>` answers `404 connection_provider_unresolved`; the bare id resolves to the first pack.
|
|
8
|
+
- New `openwop.requirement.0233.provider-registry.unique`: a schema-valid, closed registry with each bare id once, on any host with the facet.
|
|
9
|
+
- **Disposition change.** A host advertising `packsSupported` with neither `providerRead` nor the seams now records `inapplicable`, with the reason, where it recorded `blocked`. That case was a seam-only MUST, which `conformance.md` §Witness class forbids; RFC 0233 mints the path, and `witnessable-gated` means observed when the gating capability is advertised. Without the fixture installed, the two fixture legs are `inapplicable` and uniqueness still runs.
|
|
10
|
+
- **New fixture** `connection-pack-acme-widgets-rival` (catalogued in `fixtures.md`).
|
|
11
|
+
- **Sabotage.** `lib/provider-registry-witness.test.ts` runs 11 cases against `lib/provider-registry-double.ts`, each defect failing exactly its leg. The scenario file was also run against a standalone double: conforming passes in strict mode; missing refusal, rival resolving, duplicate id and unserved read each fail; not-installed and no-facet are `inapplicable` in strict mode with nothing failing.
|
|
12
|
+
- **Host impact.** openwop-app (`connections.packsSupported` at v2, no seams in production): the three `v2-provider-conflict` rows move from `blocked` to `inapplicable` until it advertises `providerRead`; with the facet and the fixture pair they become `executed-pass`. No other host advertises `connections` at v2.
|
|
13
|
+
- **Fix: `v2-advertised-path-space-served` no longer fails a host that has retired `/v1`.** The leg read any non-`404` answer under `/v1` as "served", so a retired host answering `410 Gone` on every `/v1` path (openwop-app's ADR 0669) failed for surfaces it serves at neither address. `410` now reads as not served (RFC 9110 §15.5.11), and the leg is `inapplicable` when `protocolVersions[]` has no `1.x` member, since `versioning.md` §1.2 is an overlap rule.
|
|
14
|
+
- **Found by** openwop-app's v1-cut rehearsal (suite 2.45.11, `OPENWOP_V1_RETIRED=true`): "/audit/verify (/v1 → 410, major 2 → 404); /host/events (/v1 → 410, major 2 → 404)".
|
|
15
|
+
- **Proof** against a standalone double in strict mode: a retired host and an overlap host answering `410` on `/v1` are `inapplicable`; an overlap host serving `/v1/agents` but not `/agents` still fails; a conforming overlap host passes.
|
|
16
|
+
- **The 2.45.12 cycle opened** with RFC 0233's filing.
|
|
17
|
+
- **Two RFC 0230 rows that had no test now have one, at both majors** (`trigger-bridge-delivery` and `v2-trigger-bridge-delivery`; gated like the other signed legs on `inboundSigning`, `familyAdvertised` at major 2).
|
|
18
|
+
- `openwop.requirement.0230.stale-timestamp-refused` (§C): under `required`, a post correctly signed over a `webhook-timestamp` 600 s in the past, and again 600 s in the future, must answer `401 signature_invalid` and start no run. The subscription must stay `active`, and a current signed post must then answer `202`.
|
|
19
|
+
- `openwop.requirement.0230.signing-secret-once` (§B, SR-1): a re-read of a subscription just registered carries no `signingSecret` key at any depth, not the secret's value, and no `whsec_` string. `inapplicable` where the host serves no re-read (`404`/`405`).
|
|
20
|
+
- **Sabotage.** The scratch double enforces the 300 s window and gains two defects, `skew-accepted` and `reread-leaks-secret`; `lib/trigger-delivery-witness.test.ts` runs 18 cases, and each defect fails only the legs that own the rule. Both scenario files were run against a standalone double (major 1 behind openwop-app's captured 451a665e8 discovery document): conforming, both new rows pass; each defect fails only its own row.
|
|
21
|
+
- **Host impact.** openwop-app at major 1 and 2 serves both rules on the signed path and is expected to pass; no host gains a `blocked` row. A host without `inboundSigning` records `inapplicable`.
|
|
22
|
+
|
|
23
|
+
## [2.45.11] — 2026-10-03 — the trigger bridge is witnessed at major 2
|
|
24
|
+
|
|
25
|
+
- **New scenarios `v2-trigger-bridge-delivery` and `v2-trigger-dead-letter-read`** (major 2). They port the trigger delivery legs and RFC 0232's read rules to the v2 surface (`/trigger-subscriptions/…`, bound ids `~`-projected). They share their requirement ids with the v1 twins, as the v2 secrets witness does. Each runs only the normative-surface path: there is no trigger seam at major 2.
|
|
26
|
+
- Legs: `0083.trigger-delivery.dedup`, `.dead-letter`, `.causation` and `.runless-attempt-content-free`, through the signed ingest and `GET /trigger-subscriptions/{subscriptionId}/dead-letters`. `.runless-state-change-content-free` is `inapplicable`: no wire surface causes a state change and no seam drives one (RFC 0232 gap G2).
|
|
27
|
+
- Read rules: `0232.trigger-dead-letters.paging`, `.cursor-bound` and `.tenant-bound` (`OPENWOP_TEST_TENANT_B_API_KEY`, else `blocked`). At major 2, another tenant's bound id must be refused `403 id_tenant_mismatch` (`identity.md` §5), not `404`; the profile row says which refusal each major uses (`foreignTenantRead`). openwop-app caught this before release.
|
|
28
|
+
- **Dispositions:** `triggerBridge` absent, or `inboundSigning` not listing `standard-webhooks-1` ⇒ `inapplicable`, since major 2 has no other delivery surface. The read legs also need `triggerBridge.deadLetter`.
|
|
29
|
+
- **Why.** openwop-app's seam-free production cut (build 062381a5, suite 2.45.10) passes every trigger leg at major 1, but that bundle carries 350 seam-precondition `blocked` rows and cannot certify. Its v2 bundle certifies with 0 blocked but had no trigger rows. With these scenarios, a host that advertises `triggerBridge` at major 2 witnesses RFC 0230 and RFC 0232 on a certifiable bundle.
|
|
30
|
+
- **Shared witness.** `lib/trigger-delivery-witness.ts` takes a `MajorProfile`. The profile gains `triggerSubscriptionsPath` and `idSegment`. The major-1 files keep their own inline legs for now.
|
|
31
|
+
- **Sabotage.** `lib/trigger-delivery-witness.test.ts` runs 16 cases against the scratch double in `lib/trigger-double.ts`, and each of twelve defects fails exactly the legs that own the rule. Both scenario files were also run against a standalone double. Conforming: 7 pass, the state-change row `inapplicable`. Seven defects (dedup, refused state, causation, canary leak, foreign cursor, tenant leak, a `404` where v2 requires `403`) each fail only their own leg. With no family, in strict mode, every row is `inapplicable` and none fails. Scenarios gate on `familyAdvertised`, not `gateFamily` (the 2.45.7 strict-mode defect).
|
|
32
|
+
- **Host impact.** MyndHyve advertises `triggerBridge` at major 2 without `inboundSigning`, so every new row records `inapplicable`. openwop-app and the v2 reference host don't advertise the family at major 2. No host gains a `blocked` or failing row.
|
|
33
|
+
|
|
3
34
|
## [2.45.10] — 2026-10-03 — RFC 0232 Active: a seam-free path for the run-less trigger leg
|
|
4
35
|
|
|
5
36
|
- **`trigger-bridge-delivery` leg 4 splits in two (RFC 0232, decided question 1 (a)).** Both ids stay in the `openwop-trigger-bridge` floor; the old title-derived id is aliased to the first.
|
package/README.md
CHANGED
|
@@ -135,7 +135,7 @@ Exit code is non-zero on any failed assertion. `--certify` distinguishes: `0`
|
|
|
135
135
|
|
|
136
136
|
## What's Covered
|
|
137
137
|
|
|
138
|
-
The current suite has
|
|
138
|
+
The current suite has 594 scenario files under `src/scenarios/`.
|
|
139
139
|
- 2026-09-29 (suite 2.45.0, openwop#1763): NEW `v2-cors-preflight.test.ts` — `headers.md` §Cross-origin preflight. For every operation it preflights with `Origin`, the method, and the operation's declared request headers (plus `authorization` / `content-type` where they apply, from `spec/v2/path-manifest.json`), and reads the answer as the Fetch standard's CORS-preflight check does. Self-gated: `inapplicable` when no operation's preflight grants `OPENWOP_CORS_ORIGIN` (default `https://conformance.invalid`).
|
|
140
140
|
- 2026-09-23 (suite 2.37.0 cycle, RFC 0213): NEW `v2-sse-last-event-id-cursor.test.ts` (a `Last-Event-ID` past the log is an exclusive cursor; a malformed id, when refused, is `400 validation_error`; the cursor never changes the answer for an unknown or foreign-tenant run — public test of `event-cursor-after-authorization`), `v2-idempotency-in-flight.test.ts` (five concurrent same-key creates yield one run; each loser is a marked replay or `409 idempotency_in_flight` with no retry timing in `details`; `partial-witness` when no loser was refused in flight) and `v2-interrupt-resolve-terminal.test.ts` (a run-scoped resolve after cancel or completion is `409 interrupt_already_resolved`, never `interrupt_cancelled`). All three sit off the core-standard floor until measured on the three bundle hosts.
|
|
141
141
|
- 2026-09-03 (suite `1.157.0 -> 1.158.0`, gap G17): NEW `idempotency-concurrent-claim.test.ts` — drives the new `host-sample-test-seams.md` §25 concurrent duplicate-delivery seam for the RFC 0150 §B / `idempotency.md` §"Concurrent duplicates (Layer 2)" atomic-claim MUST, which is unconditional and had no witness of any kind. Asserts every executor mints the SAME `logicalInvocationId` **before** asserting `delivered === 1` — without the identity check a host passes by minting different ids and never colliding, one effect because nothing raced. Not profile-gated and so not opt-out-able (the obligation is unconditional); an unmounted seam records `blocked`, which is not certifiable. Graduates `layer2-invocation-claim-atomic` reference-impl -> protocol.
|
|
@@ -482,7 +482,7 @@ Server-required (added in 1.7.0):
|
|
|
482
482
|
| ------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
483
483
|
| **Redaction** | [`capabilities.md`](../spec/v1/capabilities.md) §"Secrets" + NFR-7 + §"aiProviders" | Vendor-neutral assertions that the server doesn't leak secret material. Three scenario groups: (a) discovery shape contract — `secrets` + `aiProviders` advertisements are well-formed regardless of `secrets.supported`; when `supported === true`, scopes MUST be non-empty + `resolution === 'host-managed'`; `byok ⊆ supported`. (b) bearer-token redaction — invalid Bearer canary in `Authorization` header is not echoed in the 401 response body. (c) credentialRef echo control — gated on `secrets.supported === true`; canary planted in `configurable.ai.credentialRef` MUST NOT appear in any RunEvent payload (poll-based capture; transport-agnostic). Uses runtime-built canary fixtures (`lib/canaries.ts`) that defeat static secret scanners. 6 scenarios. |
|
|
484
484
|
|
|
485
|
-
Current source tree:
|
|
485
|
+
Current source tree: 594 scenario files. Use [`coverage.md`](./coverage.md) for current grade/gap tracking.
|
|
486
486
|
|
|
487
487
|
## Remaining Gaps
|
|
488
488
|
|
package/dist/lib/profiles.js
CHANGED
|
@@ -258,7 +258,9 @@ export function isMemory(c) {
|
|
|
258
258
|
/**
|
|
259
259
|
* `openwop-trigger-bridge` predicate (RFC 0083, widened by RFC 0099). Host
|
|
260
260
|
* composes the durable inbound-work contract: advertises the `triggerBridge`,
|
|
261
|
-
* has a `deadLetter` sink
|
|
261
|
+
* has a `deadLetter` run sink (RFC 0053: where a trigger-started run that fails
|
|
262
|
+
* terminally lands; a dead-lettered DELIVERY starts no run and is read through
|
|
263
|
+
* `triggerBridge.deadLetter`, RFC 0232), and has at least one
|
|
262
264
|
* durable inbound source (queue bus, durable webhooks, scheduling, OR — per
|
|
263
265
|
* RFC 0099 — externally-ingested `email`/`form` via
|
|
264
266
|
* `triggerBridge.ingestion.externalSources[]`). Capability families are
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "core.openwop.connections.acme-widgets-rival",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"kind": "connection",
|
|
5
|
+
"engines": {
|
|
6
|
+
"openwop": ">=2.0.0 <3.0.0"
|
|
7
|
+
},
|
|
8
|
+
"provider": {
|
|
9
|
+
"id": "acme-widgets",
|
|
10
|
+
"displayName": "Acme Widgets",
|
|
11
|
+
"category": "dev",
|
|
12
|
+
"auth": {
|
|
13
|
+
"kind": "oauth2",
|
|
14
|
+
"authFlow": "pkce",
|
|
15
|
+
"scopeModel": "groups",
|
|
16
|
+
"endpoints": {
|
|
17
|
+
"authorize": "https://auth.acme-widgets.example.com/oauth/authorize",
|
|
18
|
+
"token": "https://auth.acme-widgets.example.com/oauth/token"
|
|
19
|
+
},
|
|
20
|
+
"scopes": {
|
|
21
|
+
"read": [
|
|
22
|
+
{
|
|
23
|
+
"key": "widget.read",
|
|
24
|
+
"label": "Read widgets",
|
|
25
|
+
"scopes": [
|
|
26
|
+
"widget:read"
|
|
27
|
+
]
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"write": [
|
|
31
|
+
{
|
|
32
|
+
"key": "widget.write",
|
|
33
|
+
"label": "Write widgets",
|
|
34
|
+
"scopes": [
|
|
35
|
+
"widget:write"
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"reach": {
|
|
42
|
+
"mcp": {
|
|
43
|
+
"server": {
|
|
44
|
+
"url": "https://mcp.acme-widgets.example.com/mcp/",
|
|
45
|
+
"transport": "http"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"consumerNodes": [
|
|
50
|
+
"core.openwop.mcp.invoke-tool",
|
|
51
|
+
"core.openwop.mcp.read-resource"
|
|
52
|
+
],
|
|
53
|
+
"docsUrl": "https://docs.acme-widgets.example.com/oauth"
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
"name": "core.openwop.connections.acme-widgets",
|
|
3
3
|
"version": "1.0.0",
|
|
4
4
|
"kind": "connection",
|
|
5
|
-
"engines": {
|
|
5
|
+
"engines": {
|
|
6
|
+
"openwop": ">=2.0.0 <3.0.0"
|
|
7
|
+
},
|
|
6
8
|
"provider": {
|
|
7
9
|
"id": "acme-widgets",
|
|
8
10
|
"displayName": "Acme Widgets",
|
|
@@ -17,15 +19,37 @@
|
|
|
17
19
|
},
|
|
18
20
|
"scopes": {
|
|
19
21
|
"read": [
|
|
20
|
-
{
|
|
22
|
+
{
|
|
23
|
+
"key": "widget.read",
|
|
24
|
+
"label": "Read widgets",
|
|
25
|
+
"scopes": [
|
|
26
|
+
"widget:read"
|
|
27
|
+
]
|
|
28
|
+
}
|
|
21
29
|
],
|
|
22
30
|
"write": [
|
|
23
|
-
{
|
|
31
|
+
{
|
|
32
|
+
"key": "widget.write",
|
|
33
|
+
"label": "Write widgets",
|
|
34
|
+
"scopes": [
|
|
35
|
+
"widget:write"
|
|
36
|
+
]
|
|
37
|
+
}
|
|
24
38
|
]
|
|
25
39
|
}
|
|
26
40
|
},
|
|
27
|
-
"reach": {
|
|
28
|
-
|
|
41
|
+
"reach": {
|
|
42
|
+
"mcp": {
|
|
43
|
+
"server": {
|
|
44
|
+
"url": "https://mcp.acme-widgets.example.com/mcp/",
|
|
45
|
+
"transport": "http"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"consumerNodes": [
|
|
50
|
+
"core.openwop.mcp.invoke-tool",
|
|
51
|
+
"core.openwop.mcp.read-resource"
|
|
52
|
+
],
|
|
29
53
|
"docsUrl": "https://docs.acme-widgets.example.com/oauth"
|
|
30
54
|
}
|
|
31
55
|
}
|
package/fixtures.md
CHANGED
|
@@ -823,6 +823,7 @@ The `fixtures/connection-packs/` sub-directory holds canonical connection-pack m
|
|
|
823
823
|
| ------------------------ | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
824
824
|
| `connection-pack-github` | `github` | Canonical positive manifest (oauth2 + pkce, read/write scope groups, MCP reach, the exempt `provider.auth.endpoints.token` endpoint URL). Drives manifest-valid, no-credential-material, reach-exclusive, provider-resolution, and write-reconsent scenarios. **v1 only for the resolution leg:** v1 settles a collision with a built-in by version precedence (`spec/v1/connection-packs.md:89`), so a host shipping a built-in `github` still installs this pack. |
|
|
825
825
|
| `connection-pack-acme-widgets` | `acme-widgets` | Same shape as the `github` pack over a **deliberately fictional** provider. Drives `v2-provider-conflict` (RFC 0177 §D.1). The id is fictional so that no host ships it built-in: at v2 the later registration of a bare id MUST be refused, so a real-world id made the fixture uninstallable on any host that shipped it — and the qualified-form leg recorded `blocked` on a host whose only fault was obeying §D.1. Suite 2.0.4. |
|
|
826
|
+
| `connection-pack-acme-widgets-rival` | `acme-widgets` | RFC 0233 §D: a second well-formed pack (`core.openwop.connections.acme-widgets-rival`) claiming the same fictional bare id. An operator who installs `connection-pack-acme-widgets` also attempts this one after it, so the host's registry shows a `connection_provider_conflict` refusal that `v2-provider-conflict` reads through `GET /connection-providers` without a seam. Never advertised in discovery `fixtures` (those name workflows). Both acme-widgets packs pin `engines.openwop: ">=2.0.0 <3.0.0"`: a range that admits major 1 would get v1 version precedence on a dual-major host instead of the v2 refusal (openwop-app's review, 2026-10-03). |
|
|
826
827
|
| `connection-pack-apihosts-valid` | `meta-ads` | Canonical positive `openapi`-reach manifest declaring a `provider.apiHosts` credential-egress allow-list (`["facebook.com"]`) — RFC 0120. Drives `connection-pack-apihosts` (the `apiHosts` schema + conditional-MUST + egress allow-list scenario). Negatives (IP/wildcard/port/single-label/uppercase entries, openapi-without-apiHosts) are inline mutations per suite convention. |
|
|
827
828
|
|
|
828
829
|
Negative manifests (credential material, mixed kinds, dual reach) are inline test data in the scenario files per suite convention — a deliberately-invalid fixture file would fail the automatic `fixtures-valid.test.ts` sweep.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openwop/openwop-conformance",
|
|
3
|
-
"version": "2.45.
|
|
3
|
+
"version": "2.45.12",
|
|
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.45.
|
|
59
|
+
"@openwop/spec-artifacts": "2.45.12"
|
|
60
60
|
}
|
|
61
61
|
}
|
package/requirements.json
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
"$comment": "GENERATED by conformance/scripts/generate-requirement-registry.mjs — do not edit. One record per it()/test() in src/scenarios. Ids: openwop.it.<file-stem>.<title-slug>[~n] (src/lib/requirement-ids.ts). A record with id null has an interpolated title; its run-time row is keyed by the rendered title and maps here by file+line only. Renamed ids need a row in requirement-aliases.json.",
|
|
3
3
|
"generatedFrom": "src/scenarios/*.test.ts",
|
|
4
4
|
"counts": {
|
|
5
|
-
"files":
|
|
6
|
-
"tests":
|
|
7
|
-
"withStableId":
|
|
5
|
+
"files": 669,
|
|
6
|
+
"tests": 2562,
|
|
7
|
+
"withStableId": 2562,
|
|
8
8
|
"interpolatedTitles": 0,
|
|
9
|
-
"explicitIds":
|
|
9
|
+
"explicitIds": 2439
|
|
10
10
|
},
|
|
11
11
|
"records": [
|
|
12
12
|
{
|
|
@@ -26311,7 +26311,7 @@
|
|
|
26311
26311
|
{
|
|
26312
26312
|
"id": "openwop.it.trigger-bridge-delivery.de-dups-by-dedupkey-a-repeated-delivery-is-effectively-once",
|
|
26313
26313
|
"file": "trigger-bridge-delivery.test.ts",
|
|
26314
|
-
"line":
|
|
26314
|
+
"line": 191,
|
|
26315
26315
|
"title": "de-dups by dedupKey: a repeated delivery is effectively-once",
|
|
26316
26316
|
"explicitId": "openwop.requirement.0083.trigger-delivery.dedup",
|
|
26317
26317
|
"citations": [
|
|
@@ -26347,7 +26347,7 @@
|
|
|
26347
26347
|
{
|
|
26348
26348
|
"id": "openwop.it.trigger-bridge-delivery.dead-letters-an-exhausted-or-refused-delivery-without-starting-a-run",
|
|
26349
26349
|
"file": "trigger-bridge-delivery.test.ts",
|
|
26350
|
-
"line":
|
|
26350
|
+
"line": 215,
|
|
26351
26351
|
"title": "dead-letters an exhausted or refused delivery without starting a run",
|
|
26352
26352
|
"explicitId": "openwop.requirement.0083.trigger-delivery.dead-letter",
|
|
26353
26353
|
"citations": [
|
|
@@ -26377,10 +26377,80 @@
|
|
|
26377
26377
|
}
|
|
26378
26378
|
]
|
|
26379
26379
|
},
|
|
26380
|
+
{
|
|
26381
|
+
"id": "openwop.it.trigger-bridge-delivery.refuses-a-webhook-timestamp-more-than-300-s-off-without-starting-a-run",
|
|
26382
|
+
"file": "trigger-bridge-delivery.test.ts",
|
|
26383
|
+
"line": 238,
|
|
26384
|
+
"title": "refuses a webhook-timestamp more than 300 s off without starting a run",
|
|
26385
|
+
"explicitId": "openwop.requirement.0230.stale-timestamp-refused",
|
|
26386
|
+
"citations": [
|
|
26387
|
+
{
|
|
26388
|
+
"section": "trigger-bridge.md §F.6",
|
|
26389
|
+
"requirement": null,
|
|
26390
|
+
"interpolated": true
|
|
26391
|
+
},
|
|
26392
|
+
{
|
|
26393
|
+
"section": "trigger-bridge.md §F.6",
|
|
26394
|
+
"requirement": null,
|
|
26395
|
+
"interpolated": true
|
|
26396
|
+
},
|
|
26397
|
+
{
|
|
26398
|
+
"section": "trigger-bridge.md §F.6",
|
|
26399
|
+
"requirement": null,
|
|
26400
|
+
"interpolated": true
|
|
26401
|
+
},
|
|
26402
|
+
{
|
|
26403
|
+
"section": "trigger-bridge.md §F.6",
|
|
26404
|
+
"requirement": null,
|
|
26405
|
+
"interpolated": true
|
|
26406
|
+
},
|
|
26407
|
+
{
|
|
26408
|
+
"section": "trigger-bridge.md §F.6 (RFC 0230 §C.1)",
|
|
26409
|
+
"requirement": null,
|
|
26410
|
+
"interpolated": true
|
|
26411
|
+
},
|
|
26412
|
+
{
|
|
26413
|
+
"section": "trigger-bridge.md §F.6",
|
|
26414
|
+
"requirement": null,
|
|
26415
|
+
"interpolated": true
|
|
26416
|
+
}
|
|
26417
|
+
]
|
|
26418
|
+
},
|
|
26419
|
+
{
|
|
26420
|
+
"id": "openwop.it.trigger-bridge-delivery.returns-the-signing-secret-once-a-re-read-carries-no-whsec-value",
|
|
26421
|
+
"file": "trigger-bridge-delivery.test.ts",
|
|
26422
|
+
"line": 260,
|
|
26423
|
+
"title": "returns the signing secret once: a re-read carries no whsec_ value",
|
|
26424
|
+
"explicitId": "openwop.requirement.0230.signing-secret-once",
|
|
26425
|
+
"citations": [
|
|
26426
|
+
{
|
|
26427
|
+
"section": "trigger-bridge.md §F.6",
|
|
26428
|
+
"requirement": null,
|
|
26429
|
+
"interpolated": true
|
|
26430
|
+
},
|
|
26431
|
+
{
|
|
26432
|
+
"section": "trigger-bridge.md §F.6",
|
|
26433
|
+
"requirement": null,
|
|
26434
|
+
"interpolated": true
|
|
26435
|
+
},
|
|
26436
|
+
{
|
|
26437
|
+
"section": "trigger-bridge.md §F.6 (SR-1)",
|
|
26438
|
+
"requirement": "a re-read MUST NOT carry signingSecret"
|
|
26439
|
+
},
|
|
26440
|
+
{
|
|
26441
|
+
"section": "trigger-bridge.md §F.6 (SR-1)",
|
|
26442
|
+
"requirement": "a re-read MUST NOT carry the secret's value"
|
|
26443
|
+
},
|
|
26444
|
+
{
|
|
26445
|
+
"section": "trigger-bridge.md §F.6 (SR-1)",
|
|
26446
|
+
"requirement": "a re-read MUST NOT carry any whsec_ secret"
|
|
26447
|
+
}
|
|
26448
|
+
]
|
|
26449
|
+
},
|
|
26380
26450
|
{
|
|
26381
26451
|
"id": "openwop.it.trigger-bridge-delivery.links-delivery-run-causation-on-run-started",
|
|
26382
26452
|
"file": "trigger-bridge-delivery.test.ts",
|
|
26383
|
-
"line":
|
|
26453
|
+
"line": 277,
|
|
26384
26454
|
"title": "links delivery→run causation on run.started",
|
|
26385
26455
|
"explicitId": "openwop.requirement.0083.trigger-delivery.causation",
|
|
26386
26456
|
"citations": [
|
|
@@ -26416,7 +26486,7 @@
|
|
|
26416
26486
|
{
|
|
26417
26487
|
"id": "openwop.it.trigger-bridge-delivery.keeps-a-dead-lettered-run-less-attempt-content-free",
|
|
26418
26488
|
"file": "trigger-bridge-delivery.test.ts",
|
|
26419
|
-
"line":
|
|
26489
|
+
"line": 306,
|
|
26420
26490
|
"title": "keeps a dead-lettered run-less attempt content-free",
|
|
26421
26491
|
"explicitId": "openwop.requirement.0083.trigger-delivery.runless-attempt-content-free",
|
|
26422
26492
|
"citations": [
|
|
@@ -26440,7 +26510,7 @@
|
|
|
26440
26510
|
{
|
|
26441
26511
|
"id": "openwop.it.trigger-bridge-delivery.keeps-a-run-less-subscription-state-change-content-free",
|
|
26442
26512
|
"file": "trigger-bridge-delivery.test.ts",
|
|
26443
|
-
"line":
|
|
26513
|
+
"line": 337,
|
|
26444
26514
|
"title": "keeps a run-less subscription state change content-free",
|
|
26445
26515
|
"explicitId": "openwop.requirement.0083.trigger-delivery.runless-state-change-content-free",
|
|
26446
26516
|
"citations": [
|
|
@@ -33471,40 +33541,42 @@
|
|
|
33471
33541
|
{
|
|
33472
33542
|
"id": "openwop.it.v2-provider-conflict.two-definitions-of-one-bare-provider-id-fail-closed-the-later-registration-is-re",
|
|
33473
33543
|
"file": "v2-provider-conflict.test.ts",
|
|
33474
|
-
"line":
|
|
33544
|
+
"line": 130,
|
|
33475
33545
|
"title": "two definitions of one bare provider id fail closed: the later registration is refused with connection_provider_conflict",
|
|
33476
33546
|
"explicitId": "openwop.requirement.0177.provider-conflict.fail-closed",
|
|
33477
33547
|
"citations": [
|
|
33478
33548
|
{
|
|
33479
|
-
"section":
|
|
33549
|
+
"section": null,
|
|
33480
33550
|
"requirement": null,
|
|
33481
33551
|
"interpolated": true
|
|
33482
|
-
},
|
|
33483
|
-
{
|
|
33484
|
-
"section": "connection-packs.md §\"Provider identity\" (RFC 0177 §D.1)",
|
|
33485
|
-
"requirement": "the later registration of a bare provider id MUST NOT install (no version precedence)"
|
|
33486
|
-
},
|
|
33487
|
-
{
|
|
33488
|
-
"section": "connection-packs.md §\"Provider identity\" (RFC 0177 §D.1)",
|
|
33489
|
-
"requirement": "the later registration MUST be refused with connection_provider_conflict"
|
|
33490
33552
|
}
|
|
33491
33553
|
]
|
|
33492
33554
|
},
|
|
33493
33555
|
{
|
|
33494
33556
|
"id": "openwop.it.v2-provider-conflict.the-qualified-form-packname-acme-widgets-resolves-to-the-named-pack-s-definition",
|
|
33495
33557
|
"file": "v2-provider-conflict.test.ts",
|
|
33496
|
-
"line":
|
|
33558
|
+
"line": 140,
|
|
33497
33559
|
"title": "the qualified form <packName>#acme-widgets resolves to the named pack's definition",
|
|
33498
33560
|
"explicitId": "openwop.requirement.0177.provider-conflict.qualified-form",
|
|
33499
33561
|
"citations": [
|
|
33500
33562
|
{
|
|
33501
|
-
"section":
|
|
33563
|
+
"section": null,
|
|
33502
33564
|
"requirement": null,
|
|
33503
33565
|
"interpolated": true
|
|
33504
|
-
}
|
|
33566
|
+
}
|
|
33567
|
+
]
|
|
33568
|
+
},
|
|
33569
|
+
{
|
|
33570
|
+
"id": "openwop.it.v2-provider-conflict.the-provider-registry-lists-each-bare-id-once-and-carries-no-endpoint-or-credent",
|
|
33571
|
+
"file": "v2-provider-conflict.test.ts",
|
|
33572
|
+
"line": 150,
|
|
33573
|
+
"title": "the provider registry lists each bare id once and carries no endpoint or credential (RFC 0233 §B)",
|
|
33574
|
+
"explicitId": "openwop.requirement.0233.provider-registry.unique",
|
|
33575
|
+
"citations": [
|
|
33505
33576
|
{
|
|
33506
|
-
"section":
|
|
33507
|
-
"requirement":
|
|
33577
|
+
"section": null,
|
|
33578
|
+
"requirement": null,
|
|
33579
|
+
"interpolated": true
|
|
33508
33580
|
}
|
|
33509
33581
|
]
|
|
33510
33582
|
},
|
|
@@ -35267,6 +35339,145 @@
|
|
|
35267
35339
|
}
|
|
35268
35340
|
]
|
|
35269
35341
|
},
|
|
35342
|
+
{
|
|
35343
|
+
"id": "openwop.it.v2-trigger-bridge-delivery.de-dups-a-repeated-webhook-id-effectively-once",
|
|
35344
|
+
"file": "v2-trigger-bridge-delivery.test.ts",
|
|
35345
|
+
"line": 68,
|
|
35346
|
+
"title": "de-dups a repeated webhook-id: effectively-once",
|
|
35347
|
+
"explicitId": "openwop.requirement.0083.trigger-delivery.dedup",
|
|
35348
|
+
"citations": [
|
|
35349
|
+
{
|
|
35350
|
+
"section": null,
|
|
35351
|
+
"requirement": null,
|
|
35352
|
+
"interpolated": true
|
|
35353
|
+
}
|
|
35354
|
+
]
|
|
35355
|
+
},
|
|
35356
|
+
{
|
|
35357
|
+
"id": "openwop.it.v2-trigger-bridge-delivery.a-refused-post-starts-no-run-and-leaves-the-subscription-active",
|
|
35358
|
+
"file": "v2-trigger-bridge-delivery.test.ts",
|
|
35359
|
+
"line": 78,
|
|
35360
|
+
"title": "a refused post starts no run and leaves the subscription active",
|
|
35361
|
+
"explicitId": "openwop.requirement.0083.trigger-delivery.dead-letter",
|
|
35362
|
+
"citations": [
|
|
35363
|
+
{
|
|
35364
|
+
"section": null,
|
|
35365
|
+
"requirement": null,
|
|
35366
|
+
"interpolated": true
|
|
35367
|
+
}
|
|
35368
|
+
]
|
|
35369
|
+
},
|
|
35370
|
+
{
|
|
35371
|
+
"id": "openwop.it.v2-trigger-bridge-delivery.refuses-a-webhook-timestamp-more-than-300-s-off-without-starting-a-run",
|
|
35372
|
+
"file": "v2-trigger-bridge-delivery.test.ts",
|
|
35373
|
+
"line": 88,
|
|
35374
|
+
"title": "refuses a webhook-timestamp more than 300 s off without starting a run",
|
|
35375
|
+
"explicitId": "openwop.requirement.0230.stale-timestamp-refused",
|
|
35376
|
+
"citations": [
|
|
35377
|
+
{
|
|
35378
|
+
"section": null,
|
|
35379
|
+
"requirement": null,
|
|
35380
|
+
"interpolated": true
|
|
35381
|
+
}
|
|
35382
|
+
]
|
|
35383
|
+
},
|
|
35384
|
+
{
|
|
35385
|
+
"id": "openwop.it.v2-trigger-bridge-delivery.returns-the-signing-secret-once-a-re-read-carries-no-whsec-value",
|
|
35386
|
+
"file": "v2-trigger-bridge-delivery.test.ts",
|
|
35387
|
+
"line": 98,
|
|
35388
|
+
"title": "returns the signing secret once: a re-read carries no whsec_ value",
|
|
35389
|
+
"explicitId": "openwop.requirement.0230.signing-secret-once",
|
|
35390
|
+
"citations": [
|
|
35391
|
+
{
|
|
35392
|
+
"section": null,
|
|
35393
|
+
"requirement": null,
|
|
35394
|
+
"interpolated": true
|
|
35395
|
+
}
|
|
35396
|
+
]
|
|
35397
|
+
},
|
|
35398
|
+
{
|
|
35399
|
+
"id": "openwop.it.v2-trigger-bridge-delivery.links-delivery-to-run-run-started-carries-the-delivery-as-causationid",
|
|
35400
|
+
"file": "v2-trigger-bridge-delivery.test.ts",
|
|
35401
|
+
"line": 108,
|
|
35402
|
+
"title": "links delivery to run: run.started carries the delivery as causationId",
|
|
35403
|
+
"explicitId": "openwop.requirement.0083.trigger-delivery.causation",
|
|
35404
|
+
"citations": [
|
|
35405
|
+
{
|
|
35406
|
+
"section": null,
|
|
35407
|
+
"requirement": null,
|
|
35408
|
+
"interpolated": true
|
|
35409
|
+
}
|
|
35410
|
+
]
|
|
35411
|
+
},
|
|
35412
|
+
{
|
|
35413
|
+
"id": "openwop.it.v2-trigger-bridge-delivery.keeps-a-dead-lettered-run-less-attempt-content-free",
|
|
35414
|
+
"file": "v2-trigger-bridge-delivery.test.ts",
|
|
35415
|
+
"line": 118,
|
|
35416
|
+
"title": "keeps a dead-lettered run-less attempt content-free",
|
|
35417
|
+
"explicitId": "openwop.requirement.0083.trigger-delivery.runless-attempt-content-free",
|
|
35418
|
+
"citations": [
|
|
35419
|
+
{
|
|
35420
|
+
"section": null,
|
|
35421
|
+
"requirement": null,
|
|
35422
|
+
"interpolated": true
|
|
35423
|
+
}
|
|
35424
|
+
]
|
|
35425
|
+
},
|
|
35426
|
+
{
|
|
35427
|
+
"id": "openwop.it.v2-trigger-bridge-delivery.keeps-a-run-less-subscription-state-change-content-free",
|
|
35428
|
+
"file": "v2-trigger-bridge-delivery.test.ts",
|
|
35429
|
+
"line": 128,
|
|
35430
|
+
"title": "keeps a run-less subscription state change content-free",
|
|
35431
|
+
"explicitId": "openwop.requirement.0083.trigger-delivery.runless-state-change-content-free",
|
|
35432
|
+
"citations": [
|
|
35433
|
+
{
|
|
35434
|
+
"section": "webhooks.md §Inbound triggers",
|
|
35435
|
+
"requirement": "unreachable: no major-2 surface causes a state change"
|
|
35436
|
+
}
|
|
35437
|
+
]
|
|
35438
|
+
},
|
|
35439
|
+
{
|
|
35440
|
+
"id": "openwop.it.v2-trigger-dead-letter-read.clamps-limit-and-continues-a-short-page-with-nextcursor",
|
|
35441
|
+
"file": "v2-trigger-dead-letter-read.test.ts",
|
|
35442
|
+
"line": 52,
|
|
35443
|
+
"title": "clamps limit and continues a short page with nextCursor",
|
|
35444
|
+
"explicitId": "openwop.requirement.0232.trigger-dead-letters.paging",
|
|
35445
|
+
"citations": [
|
|
35446
|
+
{
|
|
35447
|
+
"section": null,
|
|
35448
|
+
"requirement": null,
|
|
35449
|
+
"interpolated": true
|
|
35450
|
+
}
|
|
35451
|
+
]
|
|
35452
|
+
},
|
|
35453
|
+
{
|
|
35454
|
+
"id": "openwop.it.v2-trigger-dead-letter-read.refuses-a-cursor-minted-for-another-subscription",
|
|
35455
|
+
"file": "v2-trigger-dead-letter-read.test.ts",
|
|
35456
|
+
"line": 61,
|
|
35457
|
+
"title": "refuses a cursor minted for another subscription",
|
|
35458
|
+
"explicitId": "openwop.requirement.0232.trigger-dead-letters.cursor-bound",
|
|
35459
|
+
"citations": [
|
|
35460
|
+
{
|
|
35461
|
+
"section": null,
|
|
35462
|
+
"requirement": null,
|
|
35463
|
+
"interpolated": true
|
|
35464
|
+
}
|
|
35465
|
+
]
|
|
35466
|
+
},
|
|
35467
|
+
{
|
|
35468
|
+
"id": "openwop.it.v2-trigger-dead-letter-read.refuses-another-tenant-s-bound-id-403-id-tenant-mismatch-and-discloses-nothing",
|
|
35469
|
+
"file": "v2-trigger-dead-letter-read.test.ts",
|
|
35470
|
+
"line": 70,
|
|
35471
|
+
"title": "refuses another tenant's bound id 403 id_tenant_mismatch and discloses nothing",
|
|
35472
|
+
"explicitId": "openwop.requirement.0232.trigger-dead-letters.tenant-bound",
|
|
35473
|
+
"citations": [
|
|
35474
|
+
{
|
|
35475
|
+
"section": null,
|
|
35476
|
+
"requirement": null,
|
|
35477
|
+
"interpolated": true
|
|
35478
|
+
}
|
|
35479
|
+
]
|
|
35480
|
+
},
|
|
35270
35481
|
{
|
|
35271
35482
|
"id": "openwop.it.v2-unadvertised-operation-not-found.get-prompts-answers-404-not-found-when-prompts-endpointssupported-is-not-adverti",
|
|
35272
35483
|
"file": "v2-unadvertised-operation-not-found.test.ts",
|
package/scenario-majors.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "GENERATED by conformance/scripts/generate-scenario-majors.mjs (RFC 0168 §D.3). Do not edit; add a file to BOTH_MAJORS in the generator to target both majors.",
|
|
3
3
|
"counts": {
|
|
4
|
-
"files":
|
|
4
|
+
"files": 594,
|
|
5
5
|
"v1": 455,
|
|
6
|
-
"v2":
|
|
6
|
+
"v2": 154
|
|
7
7
|
},
|
|
8
8
|
"majors": {
|
|
9
9
|
"a2a-1-0-agent-card.test.ts": [
|
|
@@ -1635,6 +1635,12 @@
|
|
|
1635
1635
|
"v2-tool-catalog-annotations.test.ts": [
|
|
1636
1636
|
2
|
|
1637
1637
|
],
|
|
1638
|
+
"v2-trigger-bridge-delivery.test.ts": [
|
|
1639
|
+
2
|
|
1640
|
+
],
|
|
1641
|
+
"v2-trigger-dead-letter-read.test.ts": [
|
|
1642
|
+
2
|
|
1643
|
+
],
|
|
1638
1644
|
"v2-unadvertised-operation-not-found.test.ts": [
|
|
1639
1645
|
2
|
|
1640
1646
|
],
|