@openwop/spec-artifacts 2.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CORPUS-STAMP.json +234 -0
- package/LICENSE +201 -0
- package/README.md +7 -0
- package/api/.redocly.lint-ignore.yaml +22 -0
- package/api/asyncapi.yaml +834 -0
- package/api/grpc/openwop.proto +251 -0
- package/api/openapi.yaml +2693 -0
- package/api/redocly.yaml +23 -0
- package/api/seams-v2.yaml +680 -0
- package/api/v2/asyncapi.yaml +528 -0
- package/api/v2/openapi.yaml +3139 -0
- package/api/v2/redocly.yaml +16 -0
- package/package.json +10 -0
- package/schemas/README.md +144 -0
- package/schemas/a2a-task-state.schema.json +78 -0
- package/schemas/a2ui-surface-delta-frame.schema.json +48 -0
- package/schemas/agent-deployment-transition.schema.json +49 -0
- package/schemas/agent-deployment.schema.json +54 -0
- package/schemas/agent-eval-suite.schema.json +140 -0
- package/schemas/agent-inventory-response.schema.json +115 -0
- package/schemas/agent-manifest.schema.json +156 -0
- package/schemas/agent-org-chart.schema.json +82 -0
- package/schemas/agent-ref.schema.json +63 -0
- package/schemas/agent-roster-entry.schema.json +81 -0
- package/schemas/agent-roster-response.schema.json +21 -0
- package/schemas/ai-envelope.schema.json +134 -0
- package/schemas/annotation-create.schema.json +37 -0
- package/schemas/annotation.schema.json +56 -0
- package/schemas/artifact-type-pack-manifest.schema.json +244 -0
- package/schemas/audit-verify-result.schema.json +90 -0
- package/schemas/budget-policy.schema.json +18 -0
- package/schemas/capabilities.schema.json +4160 -0
- package/schemas/certification-bundle-v2.schema.json +118 -0
- package/schemas/channel-presence-payload.schema.json +41 -0
- package/schemas/channel-written-payload.schema.json +55 -0
- package/schemas/chat-card-pack-manifest.schema.json +253 -0
- package/schemas/compact-tool-descriptor.schema.json +51 -0
- package/schemas/compensation-policy.schema.json +64 -0
- package/schemas/conformance-certification-bundle.schema.json +86 -0
- package/schemas/connection-pack-manifest.schema.json +353 -0
- package/schemas/conversation-event.schema.json +168 -0
- package/schemas/conversation-turn.schema.json +117 -0
- package/schemas/core-conformance-mock-agent-config.schema.json +152 -0
- package/schemas/credential-provenance.schema.json +18 -0
- package/schemas/credential-reference.schema.json +21 -0
- package/schemas/debug-bundle.schema.json +196 -0
- package/schemas/dispatch-config.schema.json +112 -0
- package/schemas/envelopes/clarification.request.schema.json +52 -0
- package/schemas/envelopes/error.schema.json +30 -0
- package/schemas/envelopes/media.audio.schema.json +38 -0
- package/schemas/envelopes/media.file.schema.json +37 -0
- package/schemas/envelopes/media.image.schema.json +33 -0
- package/schemas/envelopes/schema.request.schema.json +26 -0
- package/schemas/envelopes/schema.response.schema.json +22 -0
- package/schemas/envelopes/ui.a2ui-surface.schema.json +154 -0
- package/schemas/error-envelope.schema.json +25 -0
- package/schemas/eval-summary.schema.json +92 -0
- package/schemas/export-bundle.schema.json +66 -0
- package/schemas/form-content-pack-manifest.schema.json +243 -0
- package/schemas/frontend-plugin-manifest.schema.json +109 -0
- package/schemas/goal.schema.json +104 -0
- package/schemas/heartbeat-evaluated.schema.json +14 -0
- package/schemas/heartbeat-state-changed.schema.json +14 -0
- package/schemas/localized-content-language-settings.schema.json +26 -0
- package/schemas/localized-content-page-response.schema.json +60 -0
- package/schemas/localized-content-page.schema.json +62 -0
- package/schemas/localized-content-section.schema.json +51 -0
- package/schemas/memory-entry.schema.json +36 -0
- package/schemas/memory-list-options.schema.json +37 -0
- package/schemas/node-pack-manifest.schema.json +654 -0
- package/schemas/orchestrator-decision.schema.json +90 -0
- package/schemas/org-chart-responsibility-view.schema.json +26 -0
- package/schemas/pack-lockfile.schema.json +108 -0
- package/schemas/prompt-kind.schema.json +8 -0
- package/schemas/prompt-pack-manifest.schema.json +117 -0
- package/schemas/prompt-ref.schema.json +40 -0
- package/schemas/prompt-template.schema.json +149 -0
- package/schemas/proposal.schema.json +84 -0
- package/schemas/registry-version-manifest.schema.json +208 -0
- package/schemas/residency.schema.json +16 -0
- package/schemas/run-ancestry-response.schema.json +54 -0
- package/schemas/run-diff-response.schema.json +64 -0
- package/schemas/run-event-payloads.schema.json +4452 -0
- package/schemas/run-event.schema.json +211 -0
- package/schemas/run-options.schema.json +80 -0
- package/schemas/run-orchestrator-decided-event.schema.json +20 -0
- package/schemas/run-snapshot.schema.json +148 -0
- package/schemas/security-advisory.schema.json +109 -0
- package/schemas/self-hosted-runner-dispatch-frame.schema.json +79 -0
- package/schemas/self-hosted-runner-registration.schema.json +53 -0
- package/schemas/self-hosted-runner-result-frame.schema.json +38 -0
- package/schemas/subject.schema.json +56 -0
- package/schemas/suspend-request.schema.json +207 -0
- package/schemas/tool-descriptor.schema.json +63 -0
- package/schemas/trigger-event.schema.json +222 -0
- package/schemas/trigger-subscription-registration.schema.json +67 -0
- package/schemas/trigger-subscription.schema.json +26 -0
- package/schemas/ui-plugin-message.schema.json +90 -0
- package/schemas/v2/a2a-task-state.schema.json +102 -0
- package/schemas/v2/a2ui-surface-delta-frame.schema.json +62 -0
- package/schemas/v2/agent-deployment-transition.schema.json +67 -0
- package/schemas/v2/agent-deployment.schema.json +68 -0
- package/schemas/v2/agent-eval-suite.schema.json +214 -0
- package/schemas/v2/agent-inventory-response.schema.json +172 -0
- package/schemas/v2/agent-manifest.schema.json +218 -0
- package/schemas/v2/agent-org-chart.schema.json +149 -0
- package/schemas/v2/agent-ref.schema.json +67 -0
- package/schemas/v2/agent-roster-entry.schema.json +104 -0
- package/schemas/v2/agent-roster-response.schema.json +27 -0
- package/schemas/v2/ai-envelope.schema.json +167 -0
- package/schemas/v2/annotation-create.schema.json +109 -0
- package/schemas/v2/annotation.schema.json +142 -0
- package/schemas/v2/artifact-type-pack-manifest.schema.json +245 -0
- package/schemas/v2/audit-verify-result.schema.json +110 -0
- package/schemas/v2/budget-policy.schema.json +61 -0
- package/schemas/v2/capabilities.schema.json +7644 -0
- package/schemas/v2/certification-bundle.schema.json +401 -0
- package/schemas/v2/channel-presence-payload.schema.json +60 -0
- package/schemas/v2/channel-written-payload.schema.json +64 -0
- package/schemas/v2/chat-card-pack-manifest.schema.json +254 -0
- package/schemas/v2/compact-tool-descriptor.schema.json +108 -0
- package/schemas/v2/compensation-policy.schema.json +91 -0
- package/schemas/v2/compensation-projection.schema.json +95 -0
- package/schemas/v2/configurable.schema.json +110 -0
- package/schemas/v2/connection-pack-manifest.schema.json +354 -0
- package/schemas/v2/conversation-event.schema.json +281 -0
- package/schemas/v2/conversation-turn.schema.json +165 -0
- package/schemas/v2/credential-provenance.schema.json +62 -0
- package/schemas/v2/credential-reference.schema.json +28 -0
- package/schemas/v2/debug-bundle.schema.json +312 -0
- package/schemas/v2/dispatch-config.schema.json +147 -0
- package/schemas/v2/effect-ledger-projection.schema.json +71 -0
- package/schemas/v2/effect-seam-manifest.schema.json +98 -0
- package/schemas/v2/envelopes/clarification.request.schema.json +59 -0
- package/schemas/v2/envelopes/error.schema.json +35 -0
- package/schemas/v2/envelopes/media.audio.schema.json +41 -0
- package/schemas/v2/envelopes/media.file.schema.json +40 -0
- package/schemas/v2/envelopes/media.image.schema.json +36 -0
- package/schemas/v2/envelopes/schema.request.schema.json +29 -0
- package/schemas/v2/envelopes/schema.response.schema.json +26 -0
- package/schemas/v2/envelopes/ui.a2ui-surface.schema.json +292 -0
- package/schemas/v2/error-envelope.schema.json +229 -0
- package/schemas/v2/eval-summary.schema.json +166 -0
- package/schemas/v2/export-bundle.schema.json +94 -0
- package/schemas/v2/form-content-pack-manifest.schema.json +241 -0
- package/schemas/v2/frontend-plugin-manifest.schema.json +152 -0
- package/schemas/v2/goal.schema.json +188 -0
- package/schemas/v2/heartbeat-evaluated.schema.json +34 -0
- package/schemas/v2/heartbeat-state-changed.schema.json +31 -0
- package/schemas/v2/ids.schema.json +31 -0
- package/schemas/v2/localized-content-language-settings.schema.json +34 -0
- package/schemas/v2/localized-content-page-response.schema.json +94 -0
- package/schemas/v2/localized-content-page.schema.json +87 -0
- package/schemas/v2/localized-content-section.schema.json +63 -0
- package/schemas/v2/memory-entry.schema.json +45 -0
- package/schemas/v2/memory-list-options.schema.json +41 -0
- package/schemas/v2/node-pack-manifest.schema.json +657 -0
- package/schemas/v2/orchestrator-decision.schema.json +120 -0
- package/schemas/v2/org-chart-responsibility-view.schema.json +36 -0
- package/schemas/v2/pack-lockfile.schema.json +139 -0
- package/schemas/v2/prompt-kind.schema.json +14 -0
- package/schemas/v2/prompt-pack-manifest.schema.json +118 -0
- package/schemas/v2/prompt-ref.schema.json +42 -0
- package/schemas/v2/prompt-template.schema.json +209 -0
- package/schemas/v2/proposal.schema.json +145 -0
- package/schemas/v2/registry-version-manifest.schema.json +292 -0
- package/schemas/v2/residency.schema.json +19 -0
- package/schemas/v2/run-ancestry-response.schema.json +68 -0
- package/schemas/v2/run-diff-response.schema.json +80 -0
- package/schemas/v2/run-event-payloads.schema.json +4588 -0
- package/schemas/v2/run-event.schema.json +324 -0
- package/schemas/v2/run-options.schema.json +90 -0
- package/schemas/v2/run-orchestrator-decided-event.schema.json +22 -0
- package/schemas/v2/run-snapshot.schema.json +207 -0
- package/schemas/v2/security-advisory.schema.json +138 -0
- package/schemas/v2/self-hosted-runner-dispatch-frame.schema.json +119 -0
- package/schemas/v2/self-hosted-runner-registration.schema.json +74 -0
- package/schemas/v2/self-hosted-runner-result-frame.schema.json +47 -0
- package/schemas/v2/subject-link.schema.json +69 -0
- package/schemas/v2/subject.schema.json +597 -0
- package/schemas/v2/suspend-request.schema.json +370 -0
- package/schemas/v2/tool-descriptor.schema.json +150 -0
- package/schemas/v2/trigger-event.schema.json +508 -0
- package/schemas/v2/trigger-subscription-registration.schema.json +99 -0
- package/schemas/v2/trigger-subscription.schema.json +79 -0
- package/schemas/v2/ui-plugin-message.schema.json +149 -0
- package/schemas/v2/workflow-chain-pack-manifest.schema.json +610 -0
- package/schemas/v2/workflow-definition.schema.json +864 -0
- package/schemas/v2/workload-identity.schema.json +115 -0
- package/schemas/v2/workspace-file-create.schema.json +23 -0
- package/schemas/v2/workspace-file.schema.json +45 -0
- package/schemas/workflow-chain-pack-manifest.schema.json +615 -0
- package/schemas/workflow-definition.schema.json +850 -0
- package/schemas/workload-identity.schema.json +79 -0
- package/schemas/workspace-file-create.schema.json +20 -0
- package/schemas/workspace-file.schema.json +39 -0
- package/spec/v1/alias-detectors.json +283 -0
- package/spec/v1/capability-declaration-classes.json +176 -0
- package/spec/v1/core-standard-manifest.json +423 -0
- package/spec/v1/deprecations.json +854 -0
- package/spec/v1/deprecations.schema.json +187 -0
- package/spec/v1/event-codemap.json +1089 -0
- package/spec/v1/event-codemap.schema.json +41 -0
- package/spec/v1/extensions.json +1273 -0
- package/spec/v1/gaps.json +14581 -0
- package/spec/v1/gaps.schema.json +55 -0
- package/spec/v1/migrations.json +1822 -0
- package/spec/v1/migrations.schema.json +44 -0
- package/spec/v1/operation-path-manifest.json +462 -0
- package/spec/v1/spec-gaps.json +4823 -0
- package/spec/v2/declaration.json +1862 -0
- package/spec/v2/declaration.schema.json +305 -0
- package/spec/v2/errors.json +837 -0
- package/spec/v2/event-codemap.json +1099 -0
- package/spec/v2/event-codemap.schema.json +114 -0
- package/spec/v2/ext/provider-idempotency/registry.json +6 -0
- package/spec/v2/facets/a2a.schema.json +51 -0
- package/spec/v2/facets/aiProviders.schema.json +56 -0
- package/spec/v2/facets/auth.schema.json +91 -0
- package/spec/v2/facets/heartbeat.schema.json +20 -0
- package/spec/v2/facets/interrupt.schema.json +29 -0
- package/spec/v2/facets/mcp.schema.json +81 -0
- package/spec/v2/facets/replay.schema.json +34 -0
- package/spec/v2/facets/sandbox.schema.json +31 -0
- package/spec/v2/facets/webhooks.schema.json +18 -0
- package/spec/v2/path-manifest.json +279 -0
- package/spec/v2/peer-dependency-aliases.json +165 -0
- package/spec/v2/profiles.json +45 -0
- package/spec/v2/release.json +6 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://openwop.dev/spec/v1/trigger-event.schema.json",
|
|
4
|
+
"title": "TriggerEvent",
|
|
5
|
+
"description": "RFC 0099 §F.1. The normalized external-event envelope a host hands a started run as `ctx.triggerData` when an externally-originated event (`webhook`/`email`/`form`/`stream`/`change`) is delivered to an `active` TriggerSubscription (RFC 0083). This is an IN-RUN payload only — it never appears on the durable event log; the `trigger.delivery.attempted` event stays content-free (RFC 0083 §C / SECURITY `trigger-ingestion-content-redaction`). A TriggerEvent carries exactly the per-source sub-object matching its `source`. All content is `untrusted` (SECURITY `threat-model-prompt-injection.md`).",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["source", "subscriptionId", "deliveryId", "receivedAt"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"source": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"enum": ["webhook", "email", "form", "stream", "change"],
|
|
13
|
+
"description": "Which external source originated the event. A TriggerEvent MUST carry exactly the per-source sub-object matching this value and MUST NOT carry the others (RFC 0099 §F.1; `stream`/`change` per RFC 0127)."
|
|
14
|
+
},
|
|
15
|
+
"subscriptionId": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"minLength": 1,
|
|
18
|
+
"description": "The RFC 0083 §B subscription this event was delivered to."
|
|
19
|
+
},
|
|
20
|
+
"deliveryId": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"minLength": 1,
|
|
23
|
+
"description": "Stable per-delivery id; equals the `causationId` stamped on `run.started` (RFC 0083 §C-3 / RFC 0040)."
|
|
24
|
+
},
|
|
25
|
+
"dedupKey": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"description": "The host-opaque dedup key (RFC 0083 §C-1). Present iff the subscription's `dedupEnabled`. MUST NOT embed inbound body/header content in cleartext (SECURITY `trigger-ingestion-content-redaction`)."
|
|
28
|
+
},
|
|
29
|
+
"receivedAt": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"format": "date-time",
|
|
32
|
+
"description": "When the host received the external event."
|
|
33
|
+
},
|
|
34
|
+
"verified": {
|
|
35
|
+
"type": "boolean",
|
|
36
|
+
"description": "Whether the host verified the source's authenticity (webhook signature / email DMARC / form CSRF+origin) before delivery per the subscription's `verification` policy (RFC 0099 §F.2). A run MUST be able to gate on this."
|
|
37
|
+
},
|
|
38
|
+
"contentTrust": {
|
|
39
|
+
"type": "string",
|
|
40
|
+
"enum": ["untrusted"],
|
|
41
|
+
"description": "Always `untrusted`. Inbound external content reaching an LLM node MUST be wrapped per `threat-model-prompt-injection.md` §UNTRUSTED; a TriggerEvent MUST NOT directly advance a HITL approval gate (the `prompt-injection-mcp-no-approval` invariant generalizes)."
|
|
42
|
+
},
|
|
43
|
+
"permittedPurposes": {
|
|
44
|
+
"type": "array",
|
|
45
|
+
"items": { "type": "string" },
|
|
46
|
+
"description": "RFC 0128 — OPTIONAL declared uses the receiver is permitted to make of the accompanying data. Opaque purpose strings mapped to the host's local vocabulary; carries purpose categories only, never subject identifiers or consent records. Absent ⇒ unlabelled (no constraint asserted); `[]` ⇒ no onward use permitted (NOT the same as absent). A host advertising `purposePropagation` MUST honor the RFC 0128 §3 propagation rules for this label."
|
|
47
|
+
},
|
|
48
|
+
"webhook": { "$ref": "#/$defs/WebhookEvent" },
|
|
49
|
+
"email": { "$ref": "#/$defs/EmailEvent" },
|
|
50
|
+
"form": { "$ref": "#/$defs/FormEvent" },
|
|
51
|
+
"stream": { "$ref": "#/$defs/StreamEvent" },
|
|
52
|
+
"change": { "$ref": "#/$defs/ChangeEvent" }
|
|
53
|
+
},
|
|
54
|
+
"allOf": [
|
|
55
|
+
{
|
|
56
|
+
"description": "RFC 0099 §F.1 — a TriggerEvent MUST carry exactly the per-source sub-object matching its `source` and MUST NOT carry the others.",
|
|
57
|
+
"if": { "properties": { "source": { "const": "webhook" } } },
|
|
58
|
+
"then": { "not": { "anyOf": [{ "required": ["email"] }, { "required": ["form"] }, { "required": ["stream"] }, { "required": ["change"] }] } }
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"if": { "properties": { "source": { "const": "email" } } },
|
|
62
|
+
"then": { "not": { "anyOf": [{ "required": ["webhook"] }, { "required": ["form"] }, { "required": ["stream"] }, { "required": ["change"] }] } }
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"if": { "properties": { "source": { "const": "form" } } },
|
|
66
|
+
"then": { "not": { "anyOf": [{ "required": ["webhook"] }, { "required": ["email"] }, { "required": ["stream"] }, { "required": ["change"] }] } }
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"if": { "properties": { "source": { "const": "stream" } } },
|
|
70
|
+
"then": { "not": { "anyOf": [{ "required": ["webhook"] }, { "required": ["email"] }, { "required": ["form"] }, { "required": ["change"] }] } }
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"if": { "properties": { "source": { "const": "change" } } },
|
|
74
|
+
"then": { "not": { "anyOf": [{ "required": ["webhook"] }, { "required": ["email"] }, { "required": ["form"] }, { "required": ["stream"] }] } }
|
|
75
|
+
}
|
|
76
|
+
],
|
|
77
|
+
"$defs": {
|
|
78
|
+
"WebhookEvent": {
|
|
79
|
+
"type": "object",
|
|
80
|
+
"additionalProperties": false,
|
|
81
|
+
"description": "Present iff `source == \"webhook\"`.",
|
|
82
|
+
"properties": {
|
|
83
|
+
"method": { "type": "string", "enum": ["POST", "PUT", "PATCH"] },
|
|
84
|
+
"headers": {
|
|
85
|
+
"type": "object",
|
|
86
|
+
"additionalProperties": { "type": "string" },
|
|
87
|
+
"description": "Host-allowlisted headers only — a host MUST NOT pass through `Authorization`, `Cookie`, `Proxy-Authorization`, or any header carrying credential material (RFC 0099 §F.1 / SECURITY `trigger-ingestion-content-redaction`)."
|
|
88
|
+
},
|
|
89
|
+
"body": {
|
|
90
|
+
"description": "The parsed JSON body, or a string for non-JSON. Bounded by `triggerBridge.ingestion.maxBodyBytes`."
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"EmailEvent": {
|
|
95
|
+
"type": "object",
|
|
96
|
+
"additionalProperties": false,
|
|
97
|
+
"description": "Present iff `source == \"email\"`.",
|
|
98
|
+
"properties": {
|
|
99
|
+
"from": { "type": "string" },
|
|
100
|
+
"to": { "type": "array", "items": { "type": "string" } },
|
|
101
|
+
"subject": { "type": "string" },
|
|
102
|
+
"text": { "type": "string" },
|
|
103
|
+
"html": { "type": "string" },
|
|
104
|
+
"attachments": { "type": "array", "items": { "$ref": "#/$defs/AttachmentRef" } }
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"FormEvent": {
|
|
108
|
+
"type": "object",
|
|
109
|
+
"additionalProperties": false,
|
|
110
|
+
"description": "Present iff `source == \"form\"`.",
|
|
111
|
+
"properties": {
|
|
112
|
+
"fields": { "type": "object", "additionalProperties": true, "description": "The submitted field map." },
|
|
113
|
+
"files": { "type": "array", "items": { "$ref": "#/$defs/AttachmentRef" } }
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
"StreamEvent": {
|
|
117
|
+
"type": "object",
|
|
118
|
+
"additionalProperties": false,
|
|
119
|
+
"description": "Present iff `source == \"stream\"` (RFC 0127). One message consumed from a streaming broker (Kafka / Kinesis / Pub-Sub); the host is the consumer and each delivered message normalizes to one TriggerEvent. The broker connection is a credential-brokered egress (RFC 0095), never a wire field.",
|
|
120
|
+
"properties": {
|
|
121
|
+
"topic": { "type": "string", "description": "The broker topic/stream/subscription name the message was consumed from." },
|
|
122
|
+
"partition": { "type": "integer", "minimum": 0, "description": "Broker partition/shard, where the broker has one. With `offset`, feeds the RFC 0127 §4 dedup-key guidance `(topic, partition, offset)`." },
|
|
123
|
+
"offset": { "type": "string", "description": "Broker offset / sequence number as an opaque string (brokers disagree on integer width)." },
|
|
124
|
+
"key": { "type": "string", "description": "The message key, where the broker has one." },
|
|
125
|
+
"message": { "description": "The consumed message payload — parsed JSON, or a string for non-JSON. Bounded by `triggerBridge.ingestion.maxBodyBytes`." }
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
"ChangeEvent": {
|
|
129
|
+
"type": "object",
|
|
130
|
+
"additionalProperties": false,
|
|
131
|
+
"required": ["op"],
|
|
132
|
+
"description": "Present iff `source == \"change\"` (RFC 0127). One change-data-capture record from a warehouse/database changelog. `op` is REQUIRED. The warehouse connection is a credential-brokered egress (RFC 0095), never a wire field.",
|
|
133
|
+
"properties": {
|
|
134
|
+
"op": { "type": "string", "enum": ["insert", "update", "delete"], "description": "The change operation. REQUIRED (RFC 0127 §2 / resolved Q1 — one `change` source with an `op` discriminator, not per-verb sources)." },
|
|
135
|
+
"table": { "type": "string", "description": "The source table/collection/entity name. With `changelogId`, feeds the RFC 0127 §4 dedup-key guidance `(table, changelog-id)`." },
|
|
136
|
+
"changelogId": { "type": "string", "description": "The changelog position/LSN/row-version as an opaque string." },
|
|
137
|
+
"before": { "description": "The pre-image row where the feed provides one (typically `update`/`delete`). Parsed JSON. Bounded by `triggerBridge.ingestion.maxBodyBytes`." },
|
|
138
|
+
"after": { "description": "The post-image row where the feed provides one (typically `insert`/`update`). Parsed JSON. Bounded by `triggerBridge.ingestion.maxBodyBytes`." }
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
"AttachmentRef": {
|
|
142
|
+
"type": "object",
|
|
143
|
+
"additionalProperties": false,
|
|
144
|
+
"required": ["ref"],
|
|
145
|
+
"description": "A host-internal opaque handle to a resolved attachment/upload — NEVER a raw external URL the run is expected to fetch itself (RFC 0099 §F.1/§F.4). The host resolves and ingests attachments through its SSRF guard (SECURITY `trigger-ingestion-ssrf`), then hands the run an internal ref.",
|
|
146
|
+
"properties": {
|
|
147
|
+
"ref": {
|
|
148
|
+
"type": "string",
|
|
149
|
+
"minLength": 1,
|
|
150
|
+
"description": "A host-internal opaque handle (e.g. a `host.blobStorage` key)."
|
|
151
|
+
},
|
|
152
|
+
"filename": { "type": "string" },
|
|
153
|
+
"mediaType": { "type": "string" },
|
|
154
|
+
"bytes": { "type": "integer", "minimum": 0 }
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
"examples": [
|
|
159
|
+
{
|
|
160
|
+
"source": "email",
|
|
161
|
+
"subscriptionId": "sub_7",
|
|
162
|
+
"deliveryId": "dlv_a1b2",
|
|
163
|
+
"dedupKey": "msgid:abc@in.example.com",
|
|
164
|
+
"receivedAt": "2026-06-13T18:04:11Z",
|
|
165
|
+
"verified": true,
|
|
166
|
+
"contentTrust": "untrusted",
|
|
167
|
+
"email": {
|
|
168
|
+
"from": "customer@example.org",
|
|
169
|
+
"to": ["triage-support+sub_7@in.example.com"],
|
|
170
|
+
"subject": "Cannot log in",
|
|
171
|
+
"text": "I keep getting a 403.",
|
|
172
|
+
"attachments": [{ "ref": "blob_a1", "filename": "screenshot.png", "mediaType": "image/png", "bytes": 20481 }]
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"source": "webhook",
|
|
177
|
+
"subscriptionId": "sub_9",
|
|
178
|
+
"deliveryId": "dlv_c3d4",
|
|
179
|
+
"receivedAt": "2026-06-13T18:10:00Z",
|
|
180
|
+
"verified": true,
|
|
181
|
+
"contentTrust": "untrusted",
|
|
182
|
+
"webhook": {
|
|
183
|
+
"method": "POST",
|
|
184
|
+
"headers": { "X-Event-Type": "issue.created" },
|
|
185
|
+
"body": { "issue": { "id": 42, "title": "Bug" } }
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"source": "stream",
|
|
190
|
+
"subscriptionId": "sub_12",
|
|
191
|
+
"deliveryId": "dlv_e5f6",
|
|
192
|
+
"dedupKey": "events:3:88412",
|
|
193
|
+
"receivedAt": "2026-07-06T12:00:00Z",
|
|
194
|
+
"verified": true,
|
|
195
|
+
"contentTrust": "untrusted",
|
|
196
|
+
"stream": {
|
|
197
|
+
"topic": "events",
|
|
198
|
+
"partition": 3,
|
|
199
|
+
"offset": "88412",
|
|
200
|
+
"key": "user_77",
|
|
201
|
+
"message": { "type": "page_view", "path": "/pricing" }
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"source": "change",
|
|
206
|
+
"subscriptionId": "sub_13",
|
|
207
|
+
"deliveryId": "dlv_a7b8",
|
|
208
|
+
"dedupKey": "contacts:lsn:0/1C4F9D0",
|
|
209
|
+
"receivedAt": "2026-07-06T12:01:00Z",
|
|
210
|
+
"verified": true,
|
|
211
|
+
"contentTrust": "untrusted",
|
|
212
|
+
"permittedPurposes": ["analytics"],
|
|
213
|
+
"change": {
|
|
214
|
+
"op": "update",
|
|
215
|
+
"table": "contacts",
|
|
216
|
+
"changelogId": "0/1C4F9D0",
|
|
217
|
+
"before": { "id": 77, "tier": "free" },
|
|
218
|
+
"after": { "id": 77, "tier": "pro" }
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
]
|
|
222
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://openwop.dev/spec/v1/trigger-subscription-registration.schema.json",
|
|
4
|
+
"title": "TriggerSubscriptionRegistration",
|
|
5
|
+
"description": "RFC 0099 §F.2. The portable create request for an external-event trigger subscription, served by `POST /v1/trigger-subscriptions`. Binds an external source (`webhook`/`email`/`form`) to a Workflow to start, with a dedup config and a source-authenticity verification policy. This is the unified create surface RFC 0083 UQ1 left per-source. The response returns the created `TriggerSubscription` (RFC 0083 §B) plus a source-specific `binding`; the binding secret/URL is returned ONCE at creation and is not re-fetchable in cleartext (SR-1).",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["source", "workflowId"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"source": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"enum": ["webhook", "email", "form", "stream", "change"],
|
|
13
|
+
"description": "The external source this subscription ingests. MUST appear in the host's `capabilities.triggerBridge.ingestion.externalSources[]`."
|
|
14
|
+
},
|
|
15
|
+
"workflowId": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"minLength": 1,
|
|
18
|
+
"description": "The Workflow a delivered event starts (the run's `workflowId`). MUST resolve under the caller's RFC 0048 owner triple — a registration MUST NOT bind a workflow the caller cannot start (RFC 0049 scope check)."
|
|
19
|
+
},
|
|
20
|
+
"dedupEnabled": {
|
|
21
|
+
"type": "boolean",
|
|
22
|
+
"default": true,
|
|
23
|
+
"description": "Per RFC 0083 §C-1. Defaults true for external sources — at-least-once inbound delivery without dedup is a footgun."
|
|
24
|
+
},
|
|
25
|
+
"retryPolicy": {
|
|
26
|
+
"type": "object",
|
|
27
|
+
"additionalProperties": false,
|
|
28
|
+
"description": "Delivery retry policy (RFC 0083 §C-2). Same shape as `trigger-subscription.schema.json#/properties/retryPolicy`. On exhaustion the delivery transitions to `dead-lettered` (RFC 0053).",
|
|
29
|
+
"properties": {
|
|
30
|
+
"maxAttempts": { "type": "integer", "minimum": 1, "description": "Maximum delivery attempts before dead-lettering." },
|
|
31
|
+
"backoff": { "type": "string", "enum": ["none", "fixed", "exponential"], "description": "Backoff strategy between attempts." }
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"verification": {
|
|
35
|
+
"type": "object",
|
|
36
|
+
"additionalProperties": false,
|
|
37
|
+
"description": "Source-authenticity policy. The host MUST verify per this policy BEFORE delivery and stamp `TriggerEvent.verified`; an event failing a `required` verification MUST NOT start a run (it transitions `trigger.delivery.attempted{outcome:'dead-lettered'}` with `trigger.subscription.state.changed.reason:'signature-invalid'`).",
|
|
38
|
+
"properties": {
|
|
39
|
+
"mode": {
|
|
40
|
+
"type": "string",
|
|
41
|
+
"enum": ["required", "best-effort", "none"],
|
|
42
|
+
"default": "required",
|
|
43
|
+
"description": "`required`: an unverified event is dead-lettered, no run. `best-effort`: the host verifies when it can and stamps `verified` accordingly but still delivers. `none`: no verification."
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"inputMapping": {
|
|
48
|
+
"type": "object",
|
|
49
|
+
"additionalProperties": true,
|
|
50
|
+
"description": "OPTIONAL host-extension hint mapping `TriggerEvent` fields onto the workflow's `inputs`. Non-normative shape (host-specific); absent ⇒ the run receives the whole `TriggerEvent` as `ctx.triggerData`."
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"examples": [
|
|
54
|
+
{
|
|
55
|
+
"source": "email",
|
|
56
|
+
"workflowId": "triage-support",
|
|
57
|
+
"dedupEnabled": true,
|
|
58
|
+
"verification": { "mode": "required" }
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"source": "webhook",
|
|
62
|
+
"workflowId": "ingest-jira-issue",
|
|
63
|
+
"verification": { "mode": "required" },
|
|
64
|
+
"retryPolicy": { "maxAttempts": 5, "backoff": "exponential" }
|
|
65
|
+
}
|
|
66
|
+
]
|
|
67
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://openwop.dev/spec/v1/trigger-subscription.schema.json",
|
|
4
|
+
"title": "TriggerSubscription",
|
|
5
|
+
"description": "RFC 0083 §B. A durable inbound-trigger subscription record (a webhook registration, a schedule, a queue consumer) with a standardized four-state machine layered over the existing per-source registration. Composes RFC 0052/0053/0017 + webhooks.md + RFC 0040 causation; the channel wire format stays a vendor extension (§E). Content-free of inbound payloads/credentials (SR-1).",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["subscriptionId", "source", "state"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"subscriptionId": { "type": "string", "minLength": 1, "description": "Stable host-unique id for the subscription. Correlates the §C delivery events + the management surface." },
|
|
11
|
+
"source": { "type": "string", "enum": ["webhook", "schedule", "queue", "email", "form", "stream", "change"], "description": "Which trigger source backs the subscription. Channels beyond these (Slack/Discord/SMS) bridge as a vendor extension by registering a subscription of the closest source kind (§E)." },
|
|
12
|
+
"state": { "type": "string", "enum": ["active", "paused", "failed", "dead-lettered"], "description": "The §B state. `active`: accepting + delivering; `paused`: retained, not delivering (operator-held); `failed`: delivery failing past policy (the webhooks.md circuit-breaker generalized); `dead-lettered`: terminal, deliveries routed to the RFC 0053 sink." },
|
|
13
|
+
"dedupEnabled": { "type": "boolean", "description": "When true, the host de-duplicates inbound events by `dedupKey` within the retention window (§C-1; the idempotency.md Layer-1 model applied to inbound triggers)." },
|
|
14
|
+
"retryPolicy": {
|
|
15
|
+
"type": "object",
|
|
16
|
+
"additionalProperties": false,
|
|
17
|
+
"description": "Delivery retry policy (§C-2). On exhaustion the subscription/delivery transitions to `dead-lettered` (RFC 0053).",
|
|
18
|
+
"properties": {
|
|
19
|
+
"maxAttempts": { "type": "integer", "minimum": 1, "description": "Maximum delivery attempts before dead-lettering." },
|
|
20
|
+
"backoff": { "type": "string", "enum": ["none", "fixed", "exponential"], "description": "Backoff strategy between attempts." }
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"webhookId": { "type": "string", "minLength": 1, "description": "MAY — for `source: \"webhook\"`, the existing webhooks.md register key (unchanged; the state machine layers over it)." },
|
|
24
|
+
"secretFingerprint": { "type": "string", "minLength": 1, "maxLength": 32, "description": "MAY — for `source: \"webhook\"`, an identifier for the signing secret (the `(webhookId, secretFingerprint)` register key). It MUST be a **salted or host-keyed, TRUNCATED** one-way digest (e.g. the first 8–16 hex of `HMAC(hostKey, secret)`) — NOT the raw secret (SR-1) and NOT a full unsalted `SHA256(secret)` (a full unsalted hash of a low-entropy secret is an offline brute-force / confirmation oracle). The `maxLength: 32` ceiling structurally rejects a full 64-hex digest." }
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://openwop.dev/spec/v1/ui-plugin-message.schema.json",
|
|
4
|
+
"title": "UiPluginMessage",
|
|
5
|
+
"description": "RFC 0117 (amended by RFC 0119). The `ui-plugin/1` host-RPC envelope exchanged between a sandboxed front-end plugin and its host across the isolation boundary (transport per `capabilities.uiPlugins.isolation` — browser `postMessage` for `cross-origin-iframe`, host-call for `wasm`, IPC for `process`/`container`/`vm`; the envelope shape is identical across all). Every message carries `openwop: \"ui-plugin/1\"` (the protocol version tag — a host MUST ignore messages whose tag it does not recognize) and is one of: a plugin→host `request` (a `method` from the closed allowlist + a monotonic `id` for response correlation), a host→plugin `response` (`ok` + `result` on success, or `ok:false` + `error` on failure), or a host→plugin `event` (a one-way notification, e.g. `host.themeChanged`). The host exposes ONLY the methods the plugin declared in its manifest `hostApi` AND that the host recognizes; any other method MUST be rejected with an `error` response, never silently executed (`frontend-plugin-rpc-allowlist`). `artifact.write` carries the optimistic-concurrency `version` token (RFC 0117 §Concurrency, modeled on the RFC 0059 `host.workspace` `If-Match`/ETag pattern). See `spec/v1/frontend-plugin-packs.md`.",
|
|
6
|
+
"oneOf": [
|
|
7
|
+
{ "$ref": "#/$defs/request" },
|
|
8
|
+
{ "$ref": "#/$defs/response" },
|
|
9
|
+
{ "$ref": "#/$defs/event" }
|
|
10
|
+
],
|
|
11
|
+
"$defs": {
|
|
12
|
+
"request": {
|
|
13
|
+
"type": "object",
|
|
14
|
+
"title": "UiPluginRequest",
|
|
15
|
+
"description": "Plugin→host RPC call. The host MUST reject any `method` not in BOTH the plugin's declared `hostApi` allowlist AND the host's advertised `capabilities.uiPlugins.hostApi` set, returning a `response` with `ok:false` and `error.code: \"method_not_allowed\"`.",
|
|
16
|
+
"required": ["openwop", "type", "id", "method"],
|
|
17
|
+
"additionalProperties": false,
|
|
18
|
+
"properties": {
|
|
19
|
+
"openwop": { "const": "ui-plugin/1" },
|
|
20
|
+
"type": { "const": "request" },
|
|
21
|
+
"id": {
|
|
22
|
+
"type": "integer",
|
|
23
|
+
"minimum": 0,
|
|
24
|
+
"description": "Monotonic, plugin-minted correlation id. The host's `response` echoes it verbatim."
|
|
25
|
+
},
|
|
26
|
+
"method": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"enum": ["artifact.read", "artifact.write", "host.toast", "host.navigate"]
|
|
29
|
+
},
|
|
30
|
+
"params": {
|
|
31
|
+
"type": "object",
|
|
32
|
+
"description": "Method arguments. For `artifact.write`, `params.version` is REQUIRED and carries the opaque token last returned by `artifact.read`/a prior `artifact.write` (optimistic concurrency, §Concurrency). The host MUST reject a `version` it did not mint with `error.code: \"artifact_conflict\"`.",
|
|
33
|
+
"additionalProperties": true
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
"response": {
|
|
38
|
+
"type": "object",
|
|
39
|
+
"title": "UiPluginResponse",
|
|
40
|
+
"description": "Host→plugin reply to a `request`, correlated by `id`. Exactly one of `result` (when `ok:true`) or `error` (when `ok:false`).",
|
|
41
|
+
"required": ["openwop", "type", "id", "ok"],
|
|
42
|
+
"additionalProperties": false,
|
|
43
|
+
"properties": {
|
|
44
|
+
"openwop": { "const": "ui-plugin/1" },
|
|
45
|
+
"type": { "const": "response" },
|
|
46
|
+
"id": { "type": "integer", "minimum": 0 },
|
|
47
|
+
"ok": { "type": "boolean" },
|
|
48
|
+
"result": {
|
|
49
|
+
"description": "Present iff `ok:true`. For `artifact.read` the result object carries the typed artifact payload (RFC 0071) plus an opaque `version` token. For a successful `artifact.write` the result carries the NEW opaque `version` (so the editor continues without a re-read).",
|
|
50
|
+
"type": "object",
|
|
51
|
+
"additionalProperties": true
|
|
52
|
+
},
|
|
53
|
+
"error": {
|
|
54
|
+
"description": "Present iff `ok:false`.",
|
|
55
|
+
"$ref": "#/$defs/error"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"event": {
|
|
60
|
+
"type": "object",
|
|
61
|
+
"title": "UiPluginEvent",
|
|
62
|
+
"description": "Host→plugin one-way notification (no `id`, no response). E.g. `host.themeChanged`. A plugin MUST tolerate unknown event names.",
|
|
63
|
+
"required": ["openwop", "type", "event"],
|
|
64
|
+
"additionalProperties": false,
|
|
65
|
+
"properties": {
|
|
66
|
+
"openwop": { "const": "ui-plugin/1" },
|
|
67
|
+
"type": { "const": "event" },
|
|
68
|
+
"event": { "type": "string" },
|
|
69
|
+
"data": { "type": "object", "additionalProperties": true }
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"error": {
|
|
73
|
+
"type": "object",
|
|
74
|
+
"required": ["code"],
|
|
75
|
+
"additionalProperties": false,
|
|
76
|
+
"properties": {
|
|
77
|
+
"code": {
|
|
78
|
+
"type": "string",
|
|
79
|
+
"description": "Stable error code. `method_not_allowed`: the requested `method` is not in the plugin+host allowlist (`frontend-plugin-rpc-allowlist`). `artifact_conflict`: an `artifact.write` carried a stale/unknown `version` — the host MUST NOT persist and MUST return the current `version` in `currentVersion` (optimistic concurrency, parallel to RFC 0059 `workspace_conflict`). `artifact_not_found` / `unauthorized` / `internal`: standard host-mediated failures.",
|
|
80
|
+
"enum": ["method_not_allowed", "artifact_conflict", "artifact_not_found", "unauthorized", "internal"]
|
|
81
|
+
},
|
|
82
|
+
"message": { "type": "string", "description": "Human-readable detail. MUST NOT carry secret material." },
|
|
83
|
+
"currentVersion": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"description": "Present iff `code: \"artifact_conflict\"`. The host's current opaque `version` for the artifact, so the plugin can re-read/merge and retry. Opaque: the plugin MUST round-trip it verbatim and MUST NOT parse or mint it."
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://openwop.dev/spec/v2/a2a-task-state.schema.json",
|
|
4
|
+
"title": "A2ATaskState",
|
|
5
|
+
"description": "RFC 0100 §2. The durable, persisted projection of an A2A `Task` an OpenWOP host keeps per backing run when it advertises `capabilities.a2a.durableTasks: true` — durable for the run's whole lifecycle (surviving caller disconnect, host restart within retention, and HITL pauses) so `tasks/get` returns live state after a disconnect. It is the persisted form of the `a2a-integration.md` §\"State projection (forward)\" mapping, NOT a new mapping. Content-free of run inputs/outputs/artifacts/credential material (SR-1 / `a2a-integration.md` trust boundary) — artifacts project to A2A `Artifact`s over the A2A transport, not into this record.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": [
|
|
9
|
+
"taskId",
|
|
10
|
+
"runId",
|
|
11
|
+
"state",
|
|
12
|
+
"updatedAt"
|
|
13
|
+
],
|
|
14
|
+
"properties": {
|
|
15
|
+
"taskId": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"minLength": 1,
|
|
18
|
+
"description": "The A2A Task.id. MUST equal the backing OpenWOP `runId` (a2a-integration.md §2 — 'the returned runId becomes the A2A Task.id')."
|
|
19
|
+
},
|
|
20
|
+
"runId": {
|
|
21
|
+
"$ref": "ids.schema.json#/$defs/runId",
|
|
22
|
+
"description": "The backing OpenWOP run. Bound 1:1 to `taskId`."
|
|
23
|
+
},
|
|
24
|
+
"contextId": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"description": "The A2A context_id (carried as the run tag `a2a:ctx_*` per a2a-integration.md §2)."
|
|
27
|
+
},
|
|
28
|
+
"state": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"enum": [
|
|
31
|
+
"submitted",
|
|
32
|
+
"working",
|
|
33
|
+
"input-required",
|
|
34
|
+
"auth-required",
|
|
35
|
+
"completed",
|
|
36
|
+
"failed",
|
|
37
|
+
"canceled",
|
|
38
|
+
"rejected"
|
|
39
|
+
],
|
|
40
|
+
"description": "The A2A 0.3 JSON-RPC wire form (lowercase-hyphen — a2a-integration.md §'Wire-shape spelling drift'). Projected from `run.status` per a2a-integration.md §'State projection (forward)': pending→submitted, running→working, paused→working, waiting-approval/waiting-input→input-required, completed→completed, failed→failed, cancelled→canceled. `auth-required` is carried for reverse-direction fidelity only; the forward projection never sets it (openwop has no native auth interrupt — a2a-integration.md drift point #3)."
|
|
41
|
+
},
|
|
42
|
+
"interruptKind": {
|
|
43
|
+
"type": "string",
|
|
44
|
+
"enum": [
|
|
45
|
+
"approval",
|
|
46
|
+
"clarification"
|
|
47
|
+
],
|
|
48
|
+
"description": "Present iff `state == 'input-required'`. Disambiguates a2a-integration.md drift point #2 (both approval + clarification project to INPUT_REQUIRED) — carried in `Task.metadata.openwop.interrupt.kind`, the `metadata.openwop.*` shape the doc's Future-work asks to codify."
|
|
49
|
+
},
|
|
50
|
+
"updatedAt": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"format": "date-time",
|
|
53
|
+
"description": "When the projected state last changed."
|
|
54
|
+
},
|
|
55
|
+
"pushConfig": {
|
|
56
|
+
"$ref": "#/$defs/PushConfig"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"$defs": {
|
|
60
|
+
"PushConfig": {
|
|
61
|
+
"type": "object",
|
|
62
|
+
"additionalProperties": false,
|
|
63
|
+
"required": [
|
|
64
|
+
"url"
|
|
65
|
+
],
|
|
66
|
+
"description": "RFC 0100 §4. A caller-registered A2A push-notification config for this Task.",
|
|
67
|
+
"properties": {
|
|
68
|
+
"url": {
|
|
69
|
+
"type": "string",
|
|
70
|
+
"format": "uri",
|
|
71
|
+
"description": "Caller-registered push target. The host MUST validate it through the RFC 0093 webhook-egress SSRF guard before any push (no private/loopback/link-local target) — SECURITY invariant `a2a-push-egress-ssrf`."
|
|
72
|
+
},
|
|
73
|
+
"tokenFingerprint": {
|
|
74
|
+
"type": "string",
|
|
75
|
+
"maxLength": 32,
|
|
76
|
+
"description": "MAY — a truncated/salted digest of the caller's push-auth token (NEVER the raw token; same SR-1 rule as RFC 0083's `secretFingerprint`). The A2A push HMAC details (A2A §4.3.3) stay inside the A2A layer per a2a-integration.md."
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"examples": [
|
|
82
|
+
{
|
|
83
|
+
"taskId": "run_x",
|
|
84
|
+
"runId": "run_x",
|
|
85
|
+
"contextId": "ctx_42",
|
|
86
|
+
"state": "input-required",
|
|
87
|
+
"interruptKind": "approval",
|
|
88
|
+
"updatedAt": "2026-06-13T19:00:00Z",
|
|
89
|
+
"pushConfig": {
|
|
90
|
+
"url": "https://caller.example.com/a2a/push",
|
|
91
|
+
"tokenFingerprint": "a1b2c3d4e5f6"
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"taskId": "run_y",
|
|
96
|
+
"runId": "run_y",
|
|
97
|
+
"state": "completed",
|
|
98
|
+
"updatedAt": "2026-06-13T19:05:00Z"
|
|
99
|
+
}
|
|
100
|
+
],
|
|
101
|
+
"x-openwop-seeded-from": "v1"
|
|
102
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://openwop.dev/spec/v2/a2ui-surface-delta-frame.schema.json",
|
|
4
|
+
"title": "A2uiSurfaceDeltaFrame",
|
|
5
|
+
"description": "RFC 0114. A HOST-SIDE TRANSPORT frame carrying an RFC 6902 (JSON-Patch) delta over a recorded `ui.a2ui-surface` envelope (RFC 0102). Delivered ONLY over the run event stream (`GET /v1/runs/{runId}/events`) to a subscriber that negotiated `?a2uiDelta=1`; every other consumer (the event-log read, replay, `:fork`, any non-negotiating subscriber) receives the materialized FULL surface. This is NOT a recorded-envelope shape: the canonical `ui.a2ui-surface.schema.json` envelope is UNCHANGED and always full. The consumer applies the `patch` to the surface last delivered under `surfaceRef`, then re-validates the result against the closed `catalogVersion` catalog before render (the same fail-closed validation a full surface receives, RFC 0102 §1); on ANY apply/validation failure it falls back to store-without-render and the host re-materializes the full surface.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"surfaceRef",
|
|
9
|
+
"catalogVersion",
|
|
10
|
+
"patch"
|
|
11
|
+
],
|
|
12
|
+
"additionalProperties": false,
|
|
13
|
+
"properties": {
|
|
14
|
+
"surfaceRef": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"description": "REQUIRED — the recorded `ui.a2ui-surface` envelope id this delta patches. The consumer applies `patch` to the surface last delivered under this ref.",
|
|
17
|
+
"minLength": 1
|
|
18
|
+
},
|
|
19
|
+
"catalogVersion": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"description": "REQUIRED — the A2UI catalog version. MUST equal the referenced full surface's `catalogVersion`; a catalog-version change MUST start from a fresh full surface, never a delta.",
|
|
22
|
+
"minLength": 1
|
|
23
|
+
},
|
|
24
|
+
"patch": {
|
|
25
|
+
"type": "array",
|
|
26
|
+
"minItems": 1,
|
|
27
|
+
"description": "REQUIRED — a non-empty RFC 6902 (JSON-Patch) document applied over the surface last delivered under `surfaceRef`. The `test` op is EXCLUDED (a fire-and-forget transport frame cannot act on a failed conditional); `move`/`copy` are permitted but OPTIONAL to support.",
|
|
28
|
+
"items": {
|
|
29
|
+
"type": "object",
|
|
30
|
+
"required": [
|
|
31
|
+
"op",
|
|
32
|
+
"path"
|
|
33
|
+
],
|
|
34
|
+
"additionalProperties": false,
|
|
35
|
+
"properties": {
|
|
36
|
+
"op": {
|
|
37
|
+
"enum": [
|
|
38
|
+
"add",
|
|
39
|
+
"remove",
|
|
40
|
+
"replace",
|
|
41
|
+
"move",
|
|
42
|
+
"copy"
|
|
43
|
+
],
|
|
44
|
+
"description": "RFC 6902 operation. `test` is deliberately excluded."
|
|
45
|
+
},
|
|
46
|
+
"path": {
|
|
47
|
+
"type": "string",
|
|
48
|
+
"description": "RFC 6901 JSON-Pointer into the target surface."
|
|
49
|
+
},
|
|
50
|
+
"from": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"description": "RFC 6901 JSON-Pointer source for `move`/`copy`."
|
|
53
|
+
},
|
|
54
|
+
"value": {
|
|
55
|
+
"description": "The value for `add`/`replace`. Walked by the SR-1 redaction harness exactly like a full-surface value (RFC 0114)."
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"x-openwop-seeded-from": "v1"
|
|
62
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://openwop.dev/spec/v2/agent-deployment-transition.schema.json",
|
|
4
|
+
"title": "AgentDeploymentTransition",
|
|
5
|
+
"description": "RFC 0082 §E. The request body of POST /v1/agents/{agentId}/deployments — a deployment state-transition request. The host authorizes it fail-closed against the RFC 0049 `deploy:*` scope, runs any configured RFC 0051 approvalGate, enforces the RFC 0081 eval evidence when the gate requires it, and on success emits the matching `deployment.*` event and returns the updated `agent-deployment.schema.json` record. Carries no manifest body or credential material (SR-1).",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": [
|
|
9
|
+
"version",
|
|
10
|
+
"transition"
|
|
11
|
+
],
|
|
12
|
+
"properties": {
|
|
13
|
+
"version": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"maxLength": 64,
|
|
16
|
+
"description": "The concrete agent-definition version the transition targets (matches `AgentManifest.version`)."
|
|
17
|
+
},
|
|
18
|
+
"transition": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"enum": [
|
|
21
|
+
"promote",
|
|
22
|
+
"pause",
|
|
23
|
+
"deprecate",
|
|
24
|
+
"rollback",
|
|
25
|
+
"adjust-canary"
|
|
26
|
+
],
|
|
27
|
+
"description": "The lifecycle operation. `promote`: advance toward production (draft→test→staged→active) into `toState`. `pause`: active→paused. `deprecate`: active→deprecated. `rollback`: active→rolled-back, restoring a prior version. `adjust-canary`: change the active version's `canaryPercent`. Legal transitions + the seven-state machine are normative in `agent-deployment.md` §C."
|
|
28
|
+
},
|
|
29
|
+
"toState": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"enum": [
|
|
32
|
+
"draft",
|
|
33
|
+
"test",
|
|
34
|
+
"staged",
|
|
35
|
+
"active",
|
|
36
|
+
"paused",
|
|
37
|
+
"deprecated",
|
|
38
|
+
"rolled-back"
|
|
39
|
+
],
|
|
40
|
+
"description": "MAY. The target lifecycle state for a `promote` transition. A host MUST reject a transition into a state it does not advertise in `capabilities.agents.deployment.states`."
|
|
41
|
+
},
|
|
42
|
+
"channel": {
|
|
43
|
+
"type": "string",
|
|
44
|
+
"minLength": 1,
|
|
45
|
+
"maxLength": 64,
|
|
46
|
+
"description": "MAY. The named deployment channel this transition targets (e.g. `stable`). The version becomes resolvable by `AgentRef.channel` = this value (RFC 0082 §A/§B)."
|
|
47
|
+
},
|
|
48
|
+
"canaryPercent": {
|
|
49
|
+
"type": "integer",
|
|
50
|
+
"minimum": 0,
|
|
51
|
+
"maximum": 100,
|
|
52
|
+
"description": "MAY. For `promote` to `active` or `adjust-canary`, the share of channel traffic this version takes. A host advertising `capabilities.agents.deployment.canary: false` MUST reject any value < 100."
|
|
53
|
+
},
|
|
54
|
+
"evalRunId": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"minLength": 1,
|
|
57
|
+
"description": "MAY. The RFC 0081 eval run whose `EvalSummary.passed` the gate verifies before emitting `deployment.promoted` (the §E evidence). Required when the target `approvalGate` is configured with `requiredEval`; an unmet eval gate is rejected with `eval_gate_unmet`."
|
|
58
|
+
},
|
|
59
|
+
"reason": {
|
|
60
|
+
"type": "string",
|
|
61
|
+
"minLength": 1,
|
|
62
|
+
"maxLength": 512,
|
|
63
|
+
"description": "MAY. A short redaction-safe reason label (NOT free-text content), surfaced on `deployment.rolled-back.reason`. Same posture as `run.dead_lettered.reason`."
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"x-openwop-seeded-from": "v1"
|
|
67
|
+
}
|