@openwop/openwop-conformance 1.23.0 → 1.25.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/CHANGELOG.md +12 -0
- package/README.md +2 -2
- package/api/asyncapi.yaml +54 -0
- package/api/openapi.yaml +102 -0
- package/coverage.md +10 -0
- package/dist/lib/profiles.js +16 -7
- package/fixtures/trigger-events/trigger-event-email.json +18 -0
- package/fixtures/trigger-events/trigger-subscription-registration-email.json +6 -0
- package/fixtures.md +13 -0
- package/package.json +1 -1
- package/schemas/README.md +6 -0
- package/schemas/a2a-task-state.schema.json +78 -0
- package/schemas/capabilities.schema.json +103 -1
- package/schemas/export-bundle.schema.json +66 -0
- package/schemas/goal.schema.json +104 -0
- package/schemas/proposal.schema.json +84 -0
- package/schemas/run-event-payloads.schema.json +80 -2
- package/schemas/run-event.schema.json +6 -1
- package/schemas/trigger-event.schema.json +149 -0
- package/schemas/trigger-subscription-registration.schema.json +67 -0
- package/src/lib/profiles.ts +16 -7
- package/src/scenarios/a2a-task-roundtrip.test.ts +136 -0
- package/src/scenarios/export-bundle-portability.test.ts +120 -0
- package/src/scenarios/fixtures-valid.test.ts +38 -0
- package/src/scenarios/goal-standing-continuation.test.ts +139 -0
- package/src/scenarios/proposal-reviewable-learning.test.ts +129 -0
- package/src/scenarios/trigger-ingestion.test.ts +235 -0
package/schemas/README.md
CHANGED
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
| `agent-eval-suite.schema.json` | `agent-evaluation.md` (RFC 0081) | Portable agent evaluation suite — tasks + golden/rubric `expected` + deterministic fixtures + allowed model classes + pass/fail thresholds, pack-distributed via `evalSuiteRef` |
|
|
11
11
|
| `agent-manifest.schema.json` | `node-packs.md` + agent-pack RFCs | Agent manifest entries distributed alongside node-pack manifests |
|
|
12
12
|
| `eval-summary.schema.json` | `agent-evaluation.md` (RFC 0081) | The content-free eval-run scorecard — aggregate + per-task scores/cost/latency/safety-findings + regression delta; served by `GET /v1/runs/{runId}/eval-summary` (SECURITY invariant `eval-summary-no-content-leak`) |
|
|
13
|
+
| `proposal.schema.json` | `agent-memory.md` §"Reviewable learning" (RFC 0096) | Reviewable-learning proposal — an INERT, draft-state reusable artifact (agent-pack/workflow-chain-pack/prompt-template/automation) synthesized from run traces; MUST NOT influence any run until `applied`; activation delegated to RFC 0051/0049 (SECURITY invariants `proposal-inert-until-applied`, `proposal-no-resynthesis`) |
|
|
14
|
+
| `goal.schema.json` | `agent-runtime.md` §"Standing goals" (RFC 0097) | Standing goal — a durable objective with judge-based (RFC 0090) completion + bounded (RFC 0058) continuation; completion is the judge's verdict, never client-set (SECURITY invariants `goal-continuation-bounded`, `goal-completion-judge-only`) |
|
|
15
|
+
| `export-bundle.schema.json` | `portability.md` (RFC 0098) | Portable agent-platform export bundle — a tenant's reusable estate (agents/packs/templates/connection-refs/schedules/roster/org-chart) for cross-host migration; carries NO credential values, only refs (SECURITY invariant `export-bundle-no-credential-material`) |
|
|
13
16
|
| `agent-ref.schema.json` | `agent-memory.md` + agent-identity RFC | Multi-Agent Shift Phase 1 — slim runtime AgentRef projection carried on `RunSnapshot.agent` / `runOrchestrator`, `WorkflowNode.agent?`, and `agent.*` event payloads |
|
|
14
17
|
| `agent-roster-entry.schema.json` | `agent-roster.md` (RFC 0086) | Standing agent INSTANCE — a named, tenant-scoped `host:<id>` agent (the "digital-twin employee") that references a manifest/deployment (`agentRef`) and owns a `workflows[]` portfolio; the discovery shape behind `GET /v1/agents/roster` + the `roster` inventory projection |
|
|
15
18
|
| `agent-org-chart.schema.json` | `agent-org-chart.md` (RFC 0087) | Tenant-scoped, DESCRIPTIVE grouping of roster members into departments + roles with acyclic `reportsTo` edges; carries NO authority field (every object `additionalProperties:false`) per the `org-position-no-authority-escalation` invariant; the discovery shape behind `GET /v1/agents/org-chart` |
|
|
@@ -61,6 +64,9 @@
|
|
|
61
64
|
| `credential-provenance.schema.json` | `host-capabilities.md` §"Credential provenance + egress policy" (RFC 0079) | Metadata about a host-issued credential at the tool/egress boundary — `credentialId`/`issuer`/`audiences`(+scopes/expiry/redaction/audit-correlation). Secret-free (SR-1); the §C audience-binding MUST is evaluated against `audiences`. |
|
|
62
65
|
| `security-advisory.schema.json` | `registry-operations.md` + INCIDENT-RESPONSE runbook | Registry-owned CVE advisory record at `registry/security/advisories.json`. One entry per disclosed vulnerability — id, severity, affected pack-name + SemVer range, optional fixedIn/advisoryUrl/credits. Enforced by `check-advisories.mjs` in `.github/workflows/registry-publish.yml`. |
|
|
63
66
|
| `trigger-subscription.schema.json` | `trigger-bridge.md` (RFC 0083) | Durable inbound-trigger subscription record — `subscriptionId`/`source`/`state` (active/paused/failed/dead-lettered) + `dedupEnabled`/`retryPolicy` + the webhooks.md register keys. Backs the `openwop-trigger-bridge` profile; content-free of inbound payloads (SR-1). |
|
|
67
|
+
| `trigger-event.schema.json` | `trigger-bridge.md` §F (RFC 0099) | The normalized external-event envelope handed to a started run as `ctx.triggerData` (webhook/email/form). In-run only — never event-logged; `trigger.delivery.attempted` stays content-free. Per-source one-of; `contentTrust: "untrusted"`; `AttachmentRef.ref` is a host-internal handle, never a fetchable URL (`trigger-ingestion-ssrf` / `trigger-ingestion-content-redaction`). |
|
|
68
|
+
| `trigger-subscription-registration.schema.json` | `trigger-bridge.md` §F (RFC 0099) | The `POST /v1/trigger-subscriptions` create request — binds an external `source` to a `workflowId` with a dedup config + a source-authenticity `verification` policy. The portable create surface RFC 0083 UQ1 left per-source. |
|
|
69
|
+
| `a2a-task-state.schema.json` | `a2a-integration.md` §"Async / durable Tasks" (RFC 0100) | The durable, persisted projection of an A2A `Task` an OpenWOP host keeps per backing run when `a2a.durableTasks: true` — `taskId == runId`, lowercase-hyphen `state`, `interruptKind`, optional SSRF-guarded `PushConfig`. Content-free of run inputs/outputs/artifacts (SR-1 / `a2a-push-egress-ssrf`). |
|
|
64
70
|
| `budget-policy.schema.json` | `budget-policy.md` (RFC 0084) | The reserved `budget` run-options shape — `maxTokens`/`maxCostUsd`/`maxToolCalls`/`maxRetries`/`modelAllow[]`/`modelDeny[]`/`thresholdPercent`/`onExhaustion`. Enforceable per-run spend governance; wall-time/iterations delegated to RFC 0058 (`additionalProperties:false`). Content-free events; no pricing on the wire (`budget-no-pricing-leak`). |
|
|
65
71
|
| `tool-descriptor.schema.json` | `tool-catalog.md` (RFC 0078) | Portable read-only description of one tool unifying the five tool surfaces (node-pack/workflow/mcp/connector/host-extension) — stable `toolId`, source, I/O schemas, auth/egress/approval requirements, replay policy, and `safetyTier` (`exec` ⇒ `host-extension`, RFC 0069). Returned by `GET /v1/tools`; secret-free (SR-1). |
|
|
66
72
|
| `suspend-request.schema.json` | `interrupt.md` | `InterruptPayload` with 8 `kind` discriminators (approval, clarification, external-event, custom, conversation.start, conversation.exchange, conversation.close, low-confidence) |
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://openwop.dev/spec/v1/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": ["taskId", "runId", "state", "updatedAt"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"taskId": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"minLength": 1,
|
|
13
|
+
"description": "The A2A Task.id. MUST equal the backing OpenWOP `runId` (a2a-integration.md §2 — 'the returned runId becomes the A2A Task.id')."
|
|
14
|
+
},
|
|
15
|
+
"runId": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"minLength": 1,
|
|
18
|
+
"description": "The backing OpenWOP run. Bound 1:1 to `taskId`."
|
|
19
|
+
},
|
|
20
|
+
"contextId": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"description": "The A2A context_id (carried as the run tag `a2a:ctx_*` per a2a-integration.md §2)."
|
|
23
|
+
},
|
|
24
|
+
"state": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"enum": ["submitted", "working", "input-required", "auth-required", "completed", "failed", "canceled", "rejected"],
|
|
27
|
+
"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)."
|
|
28
|
+
},
|
|
29
|
+
"interruptKind": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"enum": ["approval", "clarification"],
|
|
32
|
+
"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."
|
|
33
|
+
},
|
|
34
|
+
"updatedAt": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"format": "date-time",
|
|
37
|
+
"description": "When the projected state last changed."
|
|
38
|
+
},
|
|
39
|
+
"pushConfig": { "$ref": "#/$defs/PushConfig" }
|
|
40
|
+
},
|
|
41
|
+
"$defs": {
|
|
42
|
+
"PushConfig": {
|
|
43
|
+
"type": "object",
|
|
44
|
+
"additionalProperties": false,
|
|
45
|
+
"required": ["url"],
|
|
46
|
+
"description": "RFC 0100 §4. A caller-registered A2A push-notification config for this Task.",
|
|
47
|
+
"properties": {
|
|
48
|
+
"url": {
|
|
49
|
+
"type": "string",
|
|
50
|
+
"format": "uri",
|
|
51
|
+
"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`."
|
|
52
|
+
},
|
|
53
|
+
"tokenFingerprint": {
|
|
54
|
+
"type": "string",
|
|
55
|
+
"maxLength": 32,
|
|
56
|
+
"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."
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"examples": [
|
|
62
|
+
{
|
|
63
|
+
"taskId": "run_x",
|
|
64
|
+
"runId": "run_x",
|
|
65
|
+
"contextId": "ctx_42",
|
|
66
|
+
"state": "input-required",
|
|
67
|
+
"interruptKind": "approval",
|
|
68
|
+
"updatedAt": "2026-06-13T19:00:00Z",
|
|
69
|
+
"pushConfig": { "url": "https://caller.example.com/a2a/push", "tokenFingerprint": "a1b2c3d4e5f6" }
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"taskId": "run_y",
|
|
73
|
+
"runId": "run_y",
|
|
74
|
+
"state": "completed",
|
|
75
|
+
"updatedAt": "2026-06-13T19:05:00Z"
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
}
|
|
@@ -1119,6 +1119,54 @@
|
|
|
1119
1119
|
"type": "boolean",
|
|
1120
1120
|
"default": false,
|
|
1121
1121
|
"description": "RFC 0063 (`Active`). When `true`, host honors the optional `outputAttestation` block on `core.subWorkflow`: computes a content checksum (RFC 8785 JCS + SHA-256, the `replay.md` recipe) over a child's harvested outputs and surfaces it as the additive optional `attestation` object on the existing `core.workflowChain.event { phase: 'output.harvested' }` (RFC 0037) BEFORE applying `outputMapping`; when the config sets `requireApproval: true`, suspends the parent via an `approval` interrupt (RFC 0051) before merge and fails closed (no `accept`/`edit-accept` ⇒ no merge). Reuses RFC 0051's `approval` kind + RFC 0049 scopes for `principalScope` — no new interrupt kind, event type, or error code. Hosts that omit / `false` this flag treat `outputAttestation` as inert (blind merge, today's behavior)."
|
|
1122
|
+
},
|
|
1123
|
+
"proposals": {
|
|
1124
|
+
"type": "object",
|
|
1125
|
+
"description": "RFC 0096 (`Active`). Reviewable learning — the host synthesizes reusable artifacts (skills/packs/templates/automations) from run/tool traces as INERT, reviewable drafts that MUST NOT influence the resolution, planning, or execution of any run until an authorized principal activates them. A host advertising this serves the `/v1/host/sample/proposals` surface (promotable to `/v1/proposals`) and emits the content-free `proposal.created` / `proposal.activated` events. Activation is delegated to RFC 0051 approval-gate or RFC 0049 RBAC — no new authorization path. On `apply` the installed artifact MUST byte-match the last-persisted `artifact` (no silent re-synthesis). Hosts that omit this block do not synthesize proposals; the conformance scenarios skip cleanly.",
|
|
1126
|
+
"additionalProperties": false,
|
|
1127
|
+
"required": ["artifactKinds", "activation"],
|
|
1128
|
+
"properties": {
|
|
1129
|
+
"artifactKinds": {
|
|
1130
|
+
"type": "array",
|
|
1131
|
+
"items": { "type": "string", "enum": ["agent-pack", "workflow-chain-pack", "prompt-template", "automation"] },
|
|
1132
|
+
"uniqueItems": true,
|
|
1133
|
+
"description": "Which reusable artifact kinds the host can propose. `agent-pack` (RFC 0003), `workflow-chain-pack` (RFC 0013), `prompt-template` (RFC 0027), `automation` (RFC 0052 scheduled job)."
|
|
1134
|
+
},
|
|
1135
|
+
"duplicationDetection": {
|
|
1136
|
+
"type": "boolean",
|
|
1137
|
+
"default": false,
|
|
1138
|
+
"description": "When `true`, the host populates `Proposal.duplicateOf` with an existing artifact ref the proposal restates/overlaps (the 'Curator' duplication signal)."
|
|
1139
|
+
},
|
|
1140
|
+
"activation": {
|
|
1141
|
+
"type": "string",
|
|
1142
|
+
"enum": ["approval-gate", "direct-rbac"],
|
|
1143
|
+
"description": "`approval-gate`: `apply` MUST drive an RFC 0051 gate (role/scope/quorum, audited override) and MUST NOT install unless granted/overridden. `direct-rbac`: `apply` requires only the RFC 0049 scope the host advertises for activation."
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
},
|
|
1147
|
+
"goals": {
|
|
1148
|
+
"type": "object",
|
|
1149
|
+
"description": "RFC 0097 (`Active`). Standing goals — a durable objective with explicit completion criteria, evaluated by a host-side judge (RFC 0090 verifier or host evaluator), that keeps an agent working across turns/runs until the judge is satisfied, a declared RFC 0058 bound is crossed, or the agent escalates (RFC 0044). A host advertising this serves `/v1/host/sample/goals` (promotable to `/v1/goals`) and emits the content-free `goal.evaluated` / `goal.closed` events. Completion MUST be the judge's verdict — a client MUST NOT set `state: satisfied` directly. Continuation MUST be bounded. Hosts that omit this block do not run standing goals; the conformance scenarios skip cleanly.",
|
|
1150
|
+
"additionalProperties": false,
|
|
1151
|
+
"required": ["judge", "continuation"],
|
|
1152
|
+
"properties": {
|
|
1153
|
+
"judge": {
|
|
1154
|
+
"type": "string",
|
|
1155
|
+
"enum": ["verifier", "host"],
|
|
1156
|
+
"description": "`verifier`: completion is an RFC 0090 verifier verdict. `host`: an opaque host evaluator."
|
|
1157
|
+
},
|
|
1158
|
+
"continuation": {
|
|
1159
|
+
"type": "array",
|
|
1160
|
+
"items": { "type": "string", "enum": ["schedule", "commitment", "heartbeat", "manual"] },
|
|
1161
|
+
"uniqueItems": true,
|
|
1162
|
+
"description": "How a goal re-engages work between judge checks. `schedule` (RFC 0052), `commitment` (RFC 0068), `heartbeat` (RFC 0060), `manual`."
|
|
1163
|
+
},
|
|
1164
|
+
"requiresBounds": {
|
|
1165
|
+
"type": "boolean",
|
|
1166
|
+
"default": true,
|
|
1167
|
+
"description": "When `true` (default), a goal MUST declare valid RFC 0058 `bounds` before it may activate; a `POST /goals` without bounds returns 422. The host MUST stop continuation and set `state: bound-exceeded` when any declared bound (iteration count / accumulated cost / wall-clock deadline) is crossed."
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1122
1170
|
}
|
|
1123
1171
|
},
|
|
1124
1172
|
"additionalProperties": true
|
|
@@ -1466,7 +1514,31 @@
|
|
|
1466
1514
|
"backoff": { "type": "string", "enum": ["none", "fixed", "exponential"], "description": "Backoff strategy between attempts." }
|
|
1467
1515
|
}
|
|
1468
1516
|
},
|
|
1469
|
-
"sources": { "type": "array", "uniqueItems": true, "items": { "type": "string", "enum": ["webhook", "schedule", "queue", "email", "form"] }, "description": "Which trigger sources bridge uniformly. A source listed here MUST have a registerable `TriggerSubscription` driven through the four-state machine AND emit the two `trigger.*` events for that source — the list MUST NOT over-claim a source the host has as a feature but does not wire as a durable trigger subscription. A consumer MUST tolerate any subset." }
|
|
1517
|
+
"sources": { "type": "array", "uniqueItems": true, "items": { "type": "string", "enum": ["webhook", "schedule", "queue", "email", "form"] }, "description": "Which trigger sources bridge uniformly. A source listed here MUST have a registerable `TriggerSubscription` driven through the four-state machine AND emit the two `trigger.*` events for that source — the list MUST NOT over-claim a source the host has as a feature but does not wire as a durable trigger subscription. A consumer MUST tolerate any subset." },
|
|
1518
|
+
"ingestion": {
|
|
1519
|
+
"type": "object",
|
|
1520
|
+
"additionalProperties": false,
|
|
1521
|
+
"description": "RFC 0099 §F.3 (additive). External-event ingestion advertisement — which of `sources[]` the host actually ingests from EXTERNALLY-originated events (`webhook`/`email`/`form`), normalizing each to a `TriggerEvent` (`trigger-event.schema.json`) and starting a run. Absent ⇒ the host does NOT externally-ingest (today's behavior — schedule/queue only). A source in `externalSources[]` MUST actually accept an external event, normalize it, and start a run — over-claiming is a dishonest advertisement. A consumer MUST tolerate any subset.",
|
|
1522
|
+
"properties": {
|
|
1523
|
+
"externalSources": { "type": "array", "uniqueItems": true, "items": { "type": "string", "enum": ["webhook", "email", "form"] }, "description": "Which of `sources[]` are EXTERNALLY ingested per RFC 0099. The honesty gate — each MUST normalize to a `TriggerEvent` and start a run." },
|
|
1524
|
+
"maxBodyBytes": { "type": "integer", "minimum": 1, "description": "Inbound body cap (webhook body / email / form), reusing the RFC 0076 §B response-cap discipline." },
|
|
1525
|
+
"verification": { "type": "array", "uniqueItems": true, "items": { "type": "string", "enum": ["webhook-signature", "email-dmarc", "form-origin"] }, "description": "Which source-authenticity checks the host performs. An advertised check MUST actually be performed (RFC 0099 §F.3 / UQ1)." },
|
|
1526
|
+
"registrationEndpoint": { "type": "boolean", "description": "`true` ⇒ the host serves `POST /v1/trigger-subscriptions` (RFC 0099 §F.2) for portable external-event subscription creation." }
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
},
|
|
1531
|
+
"a2a": {
|
|
1532
|
+
"type": "object",
|
|
1533
|
+
"additionalProperties": false,
|
|
1534
|
+
"description": "RFC 0100 (`Active`). The host exposes itself as an A2A (Agent2Agent) agent. `supported: true` alone ⇒ the SYNCHRONOUS `message/send` → poll `tasks/get` round-trip already specified by `a2a-integration.md` (today's behavior — no regression). The optional `streaming`/`pushNotifications`/`durableTasks` flags gate the RFC 0100 async/durable additions (resubscribe re-attach, push config, persisted `A2ATaskState` so `tasks/get` returns live state after disconnect). Absent block ⇒ no A2A advertisement.",
|
|
1535
|
+
"required": ["supported", "agentCardUrl"],
|
|
1536
|
+
"properties": {
|
|
1537
|
+
"supported": { "type": "boolean", "description": "Host exposes itself as an A2A agent." },
|
|
1538
|
+
"agentCardUrl": { "type": "string", "format": "uri", "description": "The A2A 0.3 well-known agent card URL (`/.well-known/agent-card.json`)." },
|
|
1539
|
+
"streaming": { "type": "boolean", "description": "Host supports `message/stream` + `tasks/resubscribe` (A2A `capabilities.streaming`). Gates the RFC 0100 §3 resubscribe re-attach." },
|
|
1540
|
+
"pushNotifications": { "type": "boolean", "description": "Host supports A2A push-notification config (A2A `capabilities.push_notifications`). Gates the RFC 0100 §4 push contract; a caller-supplied `pushConfig.url` is SSRF-validated (`a2a-push-egress-ssrf`)." },
|
|
1541
|
+
"durableTasks": { "type": "boolean", "description": "RFC 0100 §2. Host PERSISTS the projected Task (`A2ATaskState`) per backing run; `tasks/get` returns live state after disconnect. Absent/false ⇒ synchronous round-trip only." }
|
|
1470
1542
|
}
|
|
1471
1543
|
},
|
|
1472
1544
|
"budget": {
|
|
@@ -1979,6 +2051,36 @@
|
|
|
1979
2051
|
}
|
|
1980
2052
|
},
|
|
1981
2053
|
"additionalProperties": false
|
|
2054
|
+
},
|
|
2055
|
+
"portability": {
|
|
2056
|
+
"type": "object",
|
|
2057
|
+
"description": "RFC 0098 (`Active`). Export/import of a tenant's reusable estate (agents 0070, packs 0003/0013, prompt templates 0027, connection *refs* 0045/0095, schedules 0052, roster/org-chart 0086/0087). An export bundle carries NO credential values — only refs to be re-bound at the destination (RFC 0046/0079). Import maps the estate onto the destination's RFC 0048 identity, MUST offer a no-write dry-run plan, MUST be idempotent, and is gated by an RFC 0049 scope. A host advertising this serves `/v1/host/sample/{export,import}` (promotable to `/v1/{export,import}`) and emits the content-free `import.applied` event. Hosts that omit this block neither export nor import; the conformance scenarios skip cleanly.",
|
|
2058
|
+
"additionalProperties": false,
|
|
2059
|
+
"properties": {
|
|
2060
|
+
"export": {
|
|
2061
|
+
"type": "boolean",
|
|
2062
|
+
"default": false,
|
|
2063
|
+
"description": "Host can emit an export bundle for the caller's tenant/workspace via `GET /export`."
|
|
2064
|
+
},
|
|
2065
|
+
"import": {
|
|
2066
|
+
"type": "boolean",
|
|
2067
|
+
"default": false,
|
|
2068
|
+
"description": "Host can import an export bundle via `POST /import`. When `true`, `dryRun` MUST also be `true` (a no-write plan preview is mandatory)."
|
|
2069
|
+
},
|
|
2070
|
+
"kinds": {
|
|
2071
|
+
"type": "array",
|
|
2072
|
+
"items": { "type": "string", "enum": ["agent", "pack", "prompt-template", "connection-ref", "schedule", "roster", "org-chart"] },
|
|
2073
|
+
"uniqueItems": true,
|
|
2074
|
+
"description": "Estate kinds this host can export/import."
|
|
2075
|
+
},
|
|
2076
|
+
"dryRun": {
|
|
2077
|
+
"type": "boolean",
|
|
2078
|
+
"default": true,
|
|
2079
|
+
"description": "Import supports a no-write plan preview (`POST /import?dryRun=true`). MUST be true if `import` is true."
|
|
2080
|
+
}
|
|
2081
|
+
},
|
|
2082
|
+
"if": { "properties": { "import": { "const": true } }, "required": ["import"] },
|
|
2083
|
+
"then": { "properties": { "dryRun": { "const": true } }, "required": ["dryRun"] }
|
|
1982
2084
|
}
|
|
1983
2085
|
},
|
|
1984
2086
|
"additionalProperties": true
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://openwop.dev/spec/v1/export-bundle.schema.json",
|
|
4
|
+
"title": "ExportBundle",
|
|
5
|
+
"description": "RFC 0098 §B. A portable agent-platform export bundle — a tenant's reusable estate (agents, packs, prompt templates, connection refs, schedules, roster/org-chart) composed for migration between openwop hosts (or import from an external platform via an adapter). The bundle MUST NOT contain credential VALUES: `connection-ref` items carry only refs/provider ids per RFC 0046/0079; the importer reports unbound refs in `secretsToRebind` and re-binds secrets at the destination. All imported entities are re-owned to the caller's RFC 0048 identity; `source.originPrincipal` is informational only and grants no access. Gated on the `portability` capability.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["bundleVersion", "source", "items"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"bundleVersion": {
|
|
11
|
+
"const": "1",
|
|
12
|
+
"description": "Bundle schema version. Importers MUST reject a bundleVersion they do not understand."
|
|
13
|
+
},
|
|
14
|
+
"source": {
|
|
15
|
+
"type": "object",
|
|
16
|
+
"additionalProperties": false,
|
|
17
|
+
"required": ["origin"],
|
|
18
|
+
"description": "Provenance of the bundle. Informational only — never a source of authority at the destination.",
|
|
19
|
+
"properties": {
|
|
20
|
+
"origin": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"minLength": 1,
|
|
23
|
+
"description": "Origin host base URL or adapter id (e.g. 'adapter:openclaw')."
|
|
24
|
+
},
|
|
25
|
+
"exportedAt": { "type": "string", "format": "date-time" },
|
|
26
|
+
"originPrincipal": {
|
|
27
|
+
"type": ["string", "null"],
|
|
28
|
+
"default": null,
|
|
29
|
+
"description": "Opaque source identity, informational only. MUST NOT grant any access at the destination."
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"items": {
|
|
34
|
+
"type": "array",
|
|
35
|
+
"description": "The estate, in arbitrary order; `dependsOn` edges define apply order (topological; a cycle is a 422).",
|
|
36
|
+
"items": {
|
|
37
|
+
"type": "object",
|
|
38
|
+
"additionalProperties": false,
|
|
39
|
+
"required": ["kind", "ref", "payload"],
|
|
40
|
+
"properties": {
|
|
41
|
+
"kind": {
|
|
42
|
+
"type": "string",
|
|
43
|
+
"enum": ["agent", "pack", "prompt-template", "connection-ref", "schedule", "roster", "org-chart"],
|
|
44
|
+
"description": "Estate kind. `agent` (RFC 0070), `pack` (RFC 0003/0013), `prompt-template` (RFC 0027), `connection-ref` (RFC 0045/0095 — refs only), `schedule` (RFC 0052), `roster` (RFC 0086), `org-chart` (RFC 0087)."
|
|
45
|
+
},
|
|
46
|
+
"ref": {
|
|
47
|
+
"type": "string",
|
|
48
|
+
"minLength": 1,
|
|
49
|
+
"description": "Stable id within the bundle, used as the target of `dependsOn` edges."
|
|
50
|
+
},
|
|
51
|
+
"dependsOn": {
|
|
52
|
+
"type": "array",
|
|
53
|
+
"items": { "type": "string" },
|
|
54
|
+
"default": [],
|
|
55
|
+
"description": "Refs of other items that MUST be applied before this one (topological order)."
|
|
56
|
+
},
|
|
57
|
+
"payload": {
|
|
58
|
+
"type": "object",
|
|
59
|
+
"description": "The kind's existing schema (RFC 0070 manifest, 0003/0013 pack, 0027 template, 0045/0095 connection *ref*, 0052 job, 0086 roster, 0087 org-chart). Deliberately open here because each kind validates against its own schema. For `connection-ref`, the payload MUST carry only refs/provider ids — a literal credential value is rejected (422).",
|
|
60
|
+
"$comment": "Intentionally open object — validated against the kind's own schema; connection-ref payloads MUST NOT contain credential values (export-bundle-no-credential-material)."
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://openwop.dev/spec/v1/goal.schema.json",
|
|
4
|
+
"title": "Goal",
|
|
5
|
+
"description": "RFC 0097 §B. A standing goal — a durable objective with explicit completion criteria, evaluated by a host-side judge (RFC 0090 verifier verdict or an opaque host evaluator), that keeps an agent working across turns and runs until the judge is satisfied, a declared RFC 0058 bound is crossed, or the agent escalates (RFC 0044). Completion MUST be the judge's verdict — a client MUST NOT set `state: satisfied` directly. Continuation MUST be bounded. `objective` and any verdict payload are SR-1 redaction-safe. Gated on the `agents.goals` capability.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["id", "objective", "state", "completion", "continuation", "bounds", "owner", "createdAt"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"id": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"minLength": 1,
|
|
13
|
+
"description": "Host-assigned identifier."
|
|
14
|
+
},
|
|
15
|
+
"objective": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"description": "The standing objective. SR-1 redaction-safe — no secrets/PII."
|
|
18
|
+
},
|
|
19
|
+
"state": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"enum": ["active", "satisfied", "escalated", "abandoned", "bound-exceeded"],
|
|
22
|
+
"description": "Lifecycle state. `satisfied` is set ONLY by the host on a judge verdict, never by a client. `bound-exceeded` is set when a declared bound is crossed; `escalated` when an RFC 0044 confidence-escalation interrupt fires against the goal; `abandoned` on explicit abandon."
|
|
23
|
+
},
|
|
24
|
+
"completion": {
|
|
25
|
+
"type": "object",
|
|
26
|
+
"additionalProperties": false,
|
|
27
|
+
"required": ["check"],
|
|
28
|
+
"description": "How the goal's completion is judged.",
|
|
29
|
+
"properties": {
|
|
30
|
+
"check": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"enum": ["verifier", "host"],
|
|
33
|
+
"description": "`verifier`: completion is an RFC 0090 verifier verdict. `host`: an opaque host evaluator."
|
|
34
|
+
},
|
|
35
|
+
"verifierRef": {
|
|
36
|
+
"type": ["string", "null"],
|
|
37
|
+
"default": null,
|
|
38
|
+
"description": "RFC 0090 verifier id when `check = verifier`."
|
|
39
|
+
},
|
|
40
|
+
"lastVerdict": {
|
|
41
|
+
"type": ["object", "null"],
|
|
42
|
+
"default": null,
|
|
43
|
+
"additionalProperties": false,
|
|
44
|
+
"description": "Most recent judge verdict. Content-free re: objective text. Non-deterministic judge output — MUST be persisted (carried in the `goal.evaluated` event / checkpoint) and never recomputed on replay/fork.",
|
|
45
|
+
"properties": {
|
|
46
|
+
"satisfied": { "type": "boolean" },
|
|
47
|
+
"confidence": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
48
|
+
"runId": { "type": "string", "description": "The run this verdict evaluated (RFC 0040 causation-compatible)." }
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"continuation": {
|
|
54
|
+
"type": "object",
|
|
55
|
+
"additionalProperties": false,
|
|
56
|
+
"required": ["mode"],
|
|
57
|
+
"description": "How the goal re-engages work between judge checks.",
|
|
58
|
+
"properties": {
|
|
59
|
+
"mode": {
|
|
60
|
+
"type": "string",
|
|
61
|
+
"enum": ["schedule", "commitment", "heartbeat", "manual"],
|
|
62
|
+
"description": "`schedule` (RFC 0052), `commitment` (RFC 0068), `heartbeat` (RFC 0060), `manual`."
|
|
63
|
+
},
|
|
64
|
+
"armRef": {
|
|
65
|
+
"type": ["string", "null"],
|
|
66
|
+
"default": null,
|
|
67
|
+
"description": "The RFC 0052 job / RFC 0068 commitment / RFC 0060 heartbeat that re-engages work for this goal."
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"bounds": {
|
|
72
|
+
"type": "object",
|
|
73
|
+
"additionalProperties": false,
|
|
74
|
+
"description": "RFC 0058 execution bounds. The host MUST stop continuation and set `state: bound-exceeded` when any declared bound is crossed. When `agents.goals.requiresBounds` is true, at least one bound MUST be present before the goal may activate.",
|
|
75
|
+
"properties": {
|
|
76
|
+
"maxLoopIterations": { "type": "integer", "minimum": 1, "description": "RFC 0058. Max contributing iterations before the goal is bound-exceeded." },
|
|
77
|
+
"runTimeoutMs": { "type": "integer", "minimum": 0, "description": "RFC 0058. Wall-clock deadline (ms) for the standing goal." },
|
|
78
|
+
"maxCostUsd": { "type": "number", "minimum": 0, "description": "RFC 0084. Accumulated cost ceiling across contributing runs." }
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"progress": {
|
|
82
|
+
"type": "object",
|
|
83
|
+
"additionalProperties": false,
|
|
84
|
+
"description": "Continuation progress so far.",
|
|
85
|
+
"properties": {
|
|
86
|
+
"iterations": { "type": "integer", "minimum": 0 },
|
|
87
|
+
"contributingRunIds": { "type": "array", "items": { "type": "string" }, "description": "RFC 0040 causation-compatible." }
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"owner": {
|
|
91
|
+
"type": "object",
|
|
92
|
+
"additionalProperties": false,
|
|
93
|
+
"required": ["tenant"],
|
|
94
|
+
"description": "RFC 0048 identity triple. Redaction-safe — `principal` is an opaque id, never PII or credential material.",
|
|
95
|
+
"properties": {
|
|
96
|
+
"tenant": { "type": "string", "minLength": 1 },
|
|
97
|
+
"workspace": { "type": "string", "minLength": 1 },
|
|
98
|
+
"principal": { "type": "string", "minLength": 1 }
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
"createdAt": { "type": "string", "format": "date-time" },
|
|
102
|
+
"updatedAt": { "type": "string", "format": "date-time" }
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://openwop.dev/spec/v1/proposal.schema.json",
|
|
4
|
+
"title": "Proposal",
|
|
5
|
+
"description": "RFC 0096 §B. A reviewable-learning proposal — an INERT, draft-state reusable artifact (skill/pack/template/automation) the host synthesized from run/tool traces, that MUST NOT influence the resolution, planning, or execution of any run while in any state other than `applied`. Activation is delegated to RFC 0051 approval-gate or RFC 0049 RBAC (no new authorization path). On `apply` the installed artifact MUST byte-match the last-persisted `artifact` (no silent re-synthesis). `rationale` and `provenance.sourceRunIds` are SR-1 redaction-safe (no secrets/PII). Gated on the `agents.proposals` capability.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["id", "kind", "state", "artifact", "provenance", "owner", "createdAt"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"id": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"minLength": 1,
|
|
13
|
+
"description": "Host-assigned identifier, stable across revisions."
|
|
14
|
+
},
|
|
15
|
+
"kind": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"enum": ["agent-pack", "workflow-chain-pack", "prompt-template", "automation"],
|
|
18
|
+
"description": "The reusable artifact kind. `agent-pack` (RFC 0003), `workflow-chain-pack` (RFC 0013), `prompt-template` (RFC 0027), `automation` (RFC 0052 scheduled job)."
|
|
19
|
+
},
|
|
20
|
+
"state": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"enum": ["draft", "revised", "applied", "rejected", "archived"],
|
|
23
|
+
"description": "Lifecycle state. Only `applied` may influence a run. `draft`/`revised` are inert; `rejected`/`archived` are terminal-inert."
|
|
24
|
+
},
|
|
25
|
+
"title": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"description": "Human-facing label. SR-1 redaction-safe."
|
|
28
|
+
},
|
|
29
|
+
"rationale": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"description": "Plain-language justification. SR-1 redaction-safe — no secrets/PII."
|
|
32
|
+
},
|
|
33
|
+
"artifact": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"description": "The proposed artifact, shaped by `kind` (an RFC 0003 pack manifest, an RFC 0013 chain pack, an RFC 0027 template, an RFC 0052 job spec). Inert until applied. Deliberately open (`additionalProperties` not constrained here) because the payload conforms to the kind's own existing schema, validated by the host at `apply` (malformed-for-kind ⇒ 422).",
|
|
36
|
+
"$comment": "Intentionally open object — the artifact body is validated against the kind's own schema, not this envelope."
|
|
37
|
+
},
|
|
38
|
+
"provenance": {
|
|
39
|
+
"type": "object",
|
|
40
|
+
"additionalProperties": false,
|
|
41
|
+
"required": ["sourceRunIds"],
|
|
42
|
+
"description": "Where the proposal came from.",
|
|
43
|
+
"properties": {
|
|
44
|
+
"sourceRunIds": {
|
|
45
|
+
"type": "array",
|
|
46
|
+
"items": { "type": "string", "minLength": 1 },
|
|
47
|
+
"description": "Runs whose traces produced this proposal (RFC 0040 causation-compatible). SR-1 redaction-safe."
|
|
48
|
+
},
|
|
49
|
+
"synthesizerModel": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"description": "Opaque identifier of the model/process that synthesized the draft."
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"duplicateOf": {
|
|
56
|
+
"type": ["string", "null"],
|
|
57
|
+
"default": null,
|
|
58
|
+
"description": "Existing artifact ref this proposal restates/overlaps, when `agents.proposals.duplicationDetection` is on. `null` when unknown or detection is off."
|
|
59
|
+
},
|
|
60
|
+
"owner": {
|
|
61
|
+
"type": "object",
|
|
62
|
+
"additionalProperties": false,
|
|
63
|
+
"required": ["tenant"],
|
|
64
|
+
"description": "RFC 0048 identity triple that owns this proposal. Redaction-safe — `principal` is an opaque id, never PII or credential material. Single-tenant hosts populate at least `tenant`.",
|
|
65
|
+
"properties": {
|
|
66
|
+
"tenant": { "type": "string", "minLength": 1, "description": "Top-level isolation boundary." },
|
|
67
|
+
"workspace": { "type": "string", "minLength": 1, "description": "Optional sub-tenant within the tenant (RFC 0048 workspace)." },
|
|
68
|
+
"principal": { "type": "string", "minLength": 1, "description": "Acting identity (user or agent) — opaque id, never PII." }
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"activation": {
|
|
72
|
+
"type": ["object", "null"],
|
|
73
|
+
"default": null,
|
|
74
|
+
"description": "Populated only when `state: applied`: the RFC 0051 approval reference (if `activation = approval-gate`) and the resulting installed artifact ref.",
|
|
75
|
+
"additionalProperties": false,
|
|
76
|
+
"properties": {
|
|
77
|
+
"approvalId": { "type": ["string", "null"], "description": "RFC 0051 approval/gate id when activation routed through an approval gate." },
|
|
78
|
+
"installedArtifactRef": { "type": "string", "description": "Ref of the artifact installed on `apply` (RFC 0043 install path)." }
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"createdAt": { "type": "string", "format": "date-time" },
|
|
82
|
+
"updatedAt": { "type": "string", "format": "date-time" }
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$id": "https://openwop.dev/spec/v1/run-event-payloads.schema.json",
|
|
4
4
|
"title": "RunEventPayloads",
|
|
5
|
-
"description": "Per-RunEventType payload schemas. The base RunEventDoc shape (run-event.schema.json) leaves `payload` permissive for forward-compat. This schema defines the canonical payload contract for each known RunEventType. Consumers MAY pin strict payload validation via `$defs.<typeId>` and `ajv.validate(schema.$defs[event.type], event.payload)`. Unknown event types MUST be tolerated (no $defs match → fold best-effort).\n\
|
|
5
|
+
"description": "Per-RunEventType payload schemas. The base RunEventDoc shape (run-event.schema.json) leaves `payload` permissive for forward-compat. This schema defines the canonical payload contract for each known RunEventType. Consumers MAY pin strict payload validation via `$defs.<typeId>` and `ajv.validate(schema.$defs[event.type], event.payload)`. Unknown event types MUST be tolerated (no $defs match → fold best-effort).\n\n100 variants from `run-event.schema.json#$defs.RunEventType` are covered, grouped into ~20 shape families with shared $defs. Naming convention: camelCase keys mirror dotted RunEventType names (e.g., `run.started` → `runStarted`).",
|
|
6
6
|
"type": "object",
|
|
7
7
|
"$defs": {
|
|
8
8
|
"_typeIndex": {
|
|
@@ -104,7 +104,12 @@
|
|
|
104
104
|
"budget.reserved": { "$ref": "#/$defs/budgetReserved" },
|
|
105
105
|
"budget.consumed": { "$ref": "#/$defs/budgetConsumed" },
|
|
106
106
|
"budget.threshold.crossed": { "$ref": "#/$defs/budgetThresholdCrossed" },
|
|
107
|
-
"budget.exhausted": { "$ref": "#/$defs/budgetExhausted" }
|
|
107
|
+
"budget.exhausted": { "$ref": "#/$defs/budgetExhausted" },
|
|
108
|
+
"proposal.created": { "$ref": "#/$defs/proposalCreated" },
|
|
109
|
+
"proposal.activated": { "$ref": "#/$defs/proposalActivated" },
|
|
110
|
+
"goal.evaluated": { "$ref": "#/$defs/goalEvaluated" },
|
|
111
|
+
"goal.closed": { "$ref": "#/$defs/goalClosed" },
|
|
112
|
+
"import.applied": { "$ref": "#/$defs/importApplied" }
|
|
108
113
|
}
|
|
109
114
|
},
|
|
110
115
|
|
|
@@ -122,6 +127,79 @@
|
|
|
122
127
|
}
|
|
123
128
|
},
|
|
124
129
|
|
|
130
|
+
"proposalCreated": {
|
|
131
|
+
"description": "RFC 0096 §D. Emitted when the host synthesizes a reviewable-learning draft. Content-free: ids / kind / content-free references only — NEVER the artifact body or the rationale text (those live behind the authed read). Redaction-safe (SECURITY invariant `proposal-inert-until-applied` covers the behavior; SR-1 covers the payload). MUST NOT be emitted unless `capabilities.agents.proposals` is advertised.",
|
|
132
|
+
"type": "object",
|
|
133
|
+
"additionalProperties": false,
|
|
134
|
+
"required": ["proposalId", "kind"],
|
|
135
|
+
"properties": {
|
|
136
|
+
"proposalId": { "type": "string", "minLength": 1, "description": "The created proposal's stable id." },
|
|
137
|
+
"kind": { "type": "string", "enum": ["agent-pack", "workflow-chain-pack", "prompt-template", "automation"], "description": "The proposed artifact kind." },
|
|
138
|
+
"sourceRunIds": { "type": "array", "items": { "type": "string" }, "description": "Runs whose traces produced the draft (RFC 0040 causation-compatible). Ids only — no trace content." },
|
|
139
|
+
"duplicateOf": { "type": ["string", "null"], "description": "Existing artifact ref the proposal restates/overlaps, when duplication detection is on; else null." }
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
"proposalActivated": {
|
|
144
|
+
"description": "RFC 0096 §D. Emitted on a successful `apply`. Content-free: ids / content-free references only — NEVER the installed artifact body. MUST NOT be emitted unless `capabilities.agents.proposals` is advertised.",
|
|
145
|
+
"type": "object",
|
|
146
|
+
"additionalProperties": false,
|
|
147
|
+
"required": ["proposalId", "kind", "installedArtifactRef"],
|
|
148
|
+
"properties": {
|
|
149
|
+
"proposalId": { "type": "string", "minLength": 1 },
|
|
150
|
+
"kind": { "type": "string", "enum": ["agent-pack", "workflow-chain-pack", "prompt-template", "automation"] },
|
|
151
|
+
"approvalId": { "type": ["string", "null"], "description": "RFC 0051 approval id when activation routed through an approval gate; null for direct-rbac." },
|
|
152
|
+
"installedArtifactRef": { "type": "string", "minLength": 1, "description": "Ref of the artifact installed on apply (RFC 0043)." }
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
|
|
156
|
+
"goalEvaluated": {
|
|
157
|
+
"description": "RFC 0097 §D. Emitted after each judge check on a standing goal. Content-free: NO objective text. The verdict (`satisfied`/`confidence`) is non-deterministic judge output — it is RECORDED here and MUST NOT be recomputed on replay/fork (`replay.md`). MUST NOT be emitted unless `capabilities.agents.goals` is advertised.",
|
|
158
|
+
"type": "object",
|
|
159
|
+
"additionalProperties": false,
|
|
160
|
+
"required": ["goalId", "satisfied", "runId", "iterations"],
|
|
161
|
+
"properties": {
|
|
162
|
+
"goalId": { "type": "string", "minLength": 1 },
|
|
163
|
+
"satisfied": { "type": "boolean", "description": "The judge's verdict for this check." },
|
|
164
|
+
"confidence": { "type": "number", "minimum": 0, "maximum": 1, "description": "Judge confidence in [0,1]." },
|
|
165
|
+
"runId": { "type": "string", "minLength": 1, "description": "The run this verdict evaluated (RFC 0040 causation-compatible)." },
|
|
166
|
+
"iterations": { "type": "integer", "minimum": 0, "description": "Contributing iterations so far." }
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
"goalClosed": {
|
|
171
|
+
"description": "RFC 0097 §D. Emitted when a standing goal stops continuation. Content-free. MUST NOT be emitted unless `capabilities.agents.goals` is advertised.",
|
|
172
|
+
"type": "object",
|
|
173
|
+
"additionalProperties": false,
|
|
174
|
+
"required": ["goalId", "finalState"],
|
|
175
|
+
"properties": {
|
|
176
|
+
"goalId": { "type": "string", "minLength": 1 },
|
|
177
|
+
"finalState": { "type": "string", "enum": ["satisfied", "escalated", "abandoned", "bound-exceeded"], "description": "Terminal state the goal closed in." }
|
|
178
|
+
}
|
|
179
|
+
},
|
|
180
|
+
|
|
181
|
+
"importApplied": {
|
|
182
|
+
"description": "RFC 0098 §D. Emitted when an estate import is applied. Content-free: counts + ref-only — NO item payloads, NO secret values (SECURITY invariant `export-bundle-no-credential-material`). MUST NOT be emitted unless `capabilities.portability` is advertised.",
|
|
183
|
+
"type": "object",
|
|
184
|
+
"additionalProperties": false,
|
|
185
|
+
"required": ["bundleOrigin", "counts"],
|
|
186
|
+
"properties": {
|
|
187
|
+
"bundleOrigin": { "type": "string", "minLength": 1, "description": "The bundle's `source.origin` — informational only." },
|
|
188
|
+
"counts": {
|
|
189
|
+
"type": "object",
|
|
190
|
+
"additionalProperties": false,
|
|
191
|
+
"description": "Per-action item tallies.",
|
|
192
|
+
"properties": {
|
|
193
|
+
"created": { "type": "integer", "minimum": 0 },
|
|
194
|
+
"updated": { "type": "integer", "minimum": 0 },
|
|
195
|
+
"skipped": { "type": "integer", "minimum": 0 },
|
|
196
|
+
"failed": { "type": "integer", "minimum": 0 }
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
"secretsToRebind": { "type": "array", "items": { "type": "string" }, "description": "Provider/ref ids whose secrets must be re-bound at the destination. Refs only — never secret values." }
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
|
|
125
203
|
"connectorAuthorized": {
|
|
126
204
|
"description": "RFC 0047 — emitted when the host acquires (or re-authorizes) a third-party OAuth token on a user's behalf via the `host.oauth` flow. Redaction-safe: carries the credential REFERENCE (RFC 0046), never token material. MUST NOT be emitted unless `capabilities.oauth.supported: true`.",
|
|
127
205
|
"type": "object",
|
|
@@ -166,7 +166,12 @@
|
|
|
166
166
|
"core.workflowChain.confidence-escalated",
|
|
167
167
|
"connector.authorized",
|
|
168
168
|
"connector.auth_expired",
|
|
169
|
-
"authorization.decided"
|
|
169
|
+
"authorization.decided",
|
|
170
|
+
"proposal.created",
|
|
171
|
+
"proposal.activated",
|
|
172
|
+
"goal.evaluated",
|
|
173
|
+
"goal.closed",
|
|
174
|
+
"import.applied"
|
|
170
175
|
]
|
|
171
176
|
}
|
|
172
177
|
}
|