@openwop/spec-artifacts 2.44.5 → 2.44.7
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 +49 -47
- package/api/seams-v2.yaml +1 -1
- package/api/v2/asyncapi.yaml +1 -1
- package/api/v2/openapi.yaml +31 -122
- package/package.json +1 -1
- package/schemas/v2/agent-ref.schema.json +2 -3
- package/schemas/v2/budget-policy.schema.json +2 -3
- package/schemas/v2/capabilities.schema.json +42 -38
- package/schemas/v2/debug-bundle.schema.json +2 -2
- package/schemas/v2/error-envelope.schema.json +282 -4
- package/schemas/v2/node-pack-manifest.schema.json +2 -2
- package/schemas/v2/prompt-ref.schema.json +2 -3
- package/schemas/v2/prompt-template.schema.json +3 -3
- package/schemas/v2/run-event-payloads.schema.json +5 -5
- package/spec/v1/alias-detectors.json +25 -1
- package/spec/v1/core-standard-manifest.json +2 -2
- package/spec/v1/deprecations.json +89 -1
- package/spec/v1/gaps.json +46 -12
- package/spec/v1/migrations.json +57 -1
- package/spec/v2/core/artifact-type-packs.md +5 -1
- package/spec/v2/core/capabilities.md +20 -22
- package/spec/v2/core/conformance.md +24 -7
- package/spec/v2/core/errors.md +17 -119
- package/spec/v2/core/events.md +7 -7
- package/spec/v2/core/execution.md +56 -16
- package/spec/v2/core/host-services.md +57 -58
- package/spec/v2/core/i18n.md +10 -10
- package/spec/v2/core/idempotency.md +3 -3
- package/spec/v2/core/identity.md +11 -9
- package/spec/v2/core/interop.md +6 -8
- package/spec/v2/core/interrupt.md +8 -8
- package/spec/v2/core/oauth.md +4 -4
- package/spec/v2/core/packs.md +11 -5
- package/spec/v2/core/persistence.md +11 -13
- package/spec/v2/core/portability.md +4 -4
- package/spec/v2/core/replay.md +8 -10
- package/spec/v2/core/runs.md +20 -7
- package/spec/v2/core/security-defaults.md +0 -2
- package/spec/v2/core/storage.md +18 -20
- package/spec/v2/core/versioning.md +4 -9
- package/spec/v2/core/webhooks.md +13 -8
- package/spec/v2/declaration.json +3 -3
- package/spec/v2/errors.json +206 -2
- package/spec/v2/facets/agents.schema.json +367 -0
- package/spec/v2/facets/aiProviders.schema.json +2 -2
- package/spec/v2/generated/error-codes.md +130 -0
- package/spec/v2/release.json +2 -2
- package/spec/v2/surface-baseline.json +38 -2
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "RFC 0002 — the agents facets, hand-decided from the v1 seed with shapes unchanged: the descriptions carry the per-facet rules the v1 agent documents made normative (execution.md §agents is the family home).",
|
|
3
|
+
"properties": {
|
|
4
|
+
"profile": {
|
|
5
|
+
"type": "string",
|
|
6
|
+
"description": "Optional named capability profile (e.g. `openwop-agents-phase-1-skeleton` for identity only, `openwop-agents-full` for orchestrator, dispatch, memory and conversation). Clients pattern-match on it to gate feature usage. Whatever the profile, a host advertising `agents` accepts run-level `RunSnapshot.agent` / `runOrchestrator`, emits `agent.reasoned`, `agent.tool-called`, `agent.tool-returned`, `agent.handoff` and `agent.decided`, and honors confidence escalation: an `agent.decided` whose `confidence` is below the run's resolved escalation threshold suspends with `node.suspended { reason: low-confidence }`."
|
|
7
|
+
},
|
|
8
|
+
"modelClasses": {
|
|
9
|
+
"type": "array",
|
|
10
|
+
"items": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"enum": [
|
|
13
|
+
"reasoning",
|
|
14
|
+
"tool-using",
|
|
15
|
+
"chat",
|
|
16
|
+
"code",
|
|
17
|
+
"vision",
|
|
18
|
+
"multimodal",
|
|
19
|
+
"embedding",
|
|
20
|
+
"classification",
|
|
21
|
+
"retrieval"
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
"uniqueItems": true,
|
|
25
|
+
"description": "Optional list of `AgentRef.modelClass` values this host supports for hosted agents. Pack manifests whose `modelClass` is not in this list MUST refuse install with `pack_runtime_requirement_unmet`."
|
|
26
|
+
},
|
|
27
|
+
"orchestratorPattern": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"description": "Optional orchestration pattern: the host's supervisor strategy. Canonical: `single`, `delegate`, `delegate.smart`. Vendor extensions ship under `vendor.<host>.<pattern>`."
|
|
30
|
+
},
|
|
31
|
+
"memoryBackends": {
|
|
32
|
+
"type": "array",
|
|
33
|
+
"items": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"enum": [
|
|
36
|
+
"long-term"
|
|
37
|
+
]
|
|
38
|
+
},
|
|
39
|
+
"uniqueItems": true,
|
|
40
|
+
"description": "Optional list of memory backends. `long-term` means the host implements `ctx.memory` (host-services.md §memory) against a durable store with the SR-1 redaction invariant intact end to end: a value the run's vault resolved is replaced by `[REDACTED:<secretId>]` before any persisted write. Hosts that do not wire a memory adapter omit this field."
|
|
41
|
+
},
|
|
42
|
+
"memoryConsolidation": {
|
|
43
|
+
"type": "object",
|
|
44
|
+
"description": "RFC 0068. Background reconciliation of LONG-TERM memory (merge, dedup, supersede, strengthen). Distinct from token-budgeted distillation of transactional memory, which emits `memory.compacted`; a host MAY implement both, independently. Requires `memoryBackends` to include `long-term`. A consolidation pass MUST (1) operate over a single `memoryRef`'s long-term entries and MUST NOT read or write another tenant's entries; (2) be idempotent over a stable corpus: a second pass over an unchanged corpus MUST NOT further reduce `outputCount`; (3) route every derived or merged entry's content through the same redaction as a fresh `put`; (4) emit the content-free `agent.memory-consolidated` (`inputCount`, `outputCount`, `memoryRef`) after the pass. Consolidation is a host-managed mutation outside the replay envelope: a run sees consolidated memory only through the read snapshot its event log records, and the event is re-read from the log on replay. A host MUST NOT re-run a pass at replay time, and a run MUST NOT trigger a pass that mutates its own read snapshot mid-run. Hosts that omit this block do not consolidate.",
|
|
45
|
+
"additionalProperties": false,
|
|
46
|
+
"properties": {
|
|
47
|
+
"schedule": {
|
|
48
|
+
"type": "string",
|
|
49
|
+
"enum": [
|
|
50
|
+
"host-managed",
|
|
51
|
+
"scheduled",
|
|
52
|
+
"on-demand"
|
|
53
|
+
],
|
|
54
|
+
"description": "How a consolidation pass is initiated. `host-managed`: a host-internal cadence clients do not control (the default when absent). `scheduled`: bound to a `capabilities.scheduling` (RFC 0052) trigger. `on-demand`: the host runs a pass when explicitly requested. A host MAY honor more than one path but advertises the primary."
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"commitments": {
|
|
59
|
+
"type": "object",
|
|
60
|
+
"description": "RFC 0068. Inferred STANDING commitments: durable, memory-derived intentions the host promotes into a time- or predicate-gated arm that fires later without a fresh user turn (time arms compose `scheduling`, predicate arms `heartbeat`). A host advertising this: MUST bind each commitment to the `memoryRef` it was inferred from, and the commitment, its `commitment.fired` event and any enqueued run MUST share that memory's tenant; MUST fire each commitment at most once per satisfied condition (once per scheduled instant for `time`, once per state transition for `predicate`) and MUST NOT re-fire one on replay; MUST emit the content-free `commitment.fired` when one fires, and MUST NOT place the inferred intention text or any secret-bearing payload on it (the redacted memory read serves the text); MAY enqueue a run when one fires, and that run inherits the source memory's tenant and is reported as `enqueuedRunId`. Hosts that omit this block do not infer commitments.",
|
|
61
|
+
"additionalProperties": false,
|
|
62
|
+
"properties": {
|
|
63
|
+
"fireConditions": {
|
|
64
|
+
"type": "array",
|
|
65
|
+
"items": {
|
|
66
|
+
"type": "string",
|
|
67
|
+
"enum": [
|
|
68
|
+
"time",
|
|
69
|
+
"predicate"
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
"uniqueItems": true,
|
|
73
|
+
"description": "Which fire-condition kinds the host supports. `time` composes RFC 0052 scheduling; `predicate` composes RFC 0060 heartbeat. Absent ⇒ `['time']`."
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"orchestrator": {
|
|
78
|
+
"type": "boolean",
|
|
79
|
+
"description": "When `true`, the host implements the `core.orchestrator.supervisor` node typeId AND honors the conservative-path suspend semantics (CP-1: low-confidence suspend via `node.suspended { reason: low-confidence }`)."
|
|
80
|
+
},
|
|
81
|
+
"dispatch": {
|
|
82
|
+
"type": "boolean",
|
|
83
|
+
"description": "When `true`, the host implements the `core.dispatch` Core typeId AND honors the conservative-path commitment CP-2 (`core.dispatch` MUST NOT mutate the run's DAG mid-run). Implies (but does NOT require) `agents.orchestrator: true`."
|
|
84
|
+
},
|
|
85
|
+
"manifestRuntime": {
|
|
86
|
+
"type": "object",
|
|
87
|
+
"description": "RFC 0070. Agent-manifest runtime floor — the minimal tier that makes a published agent pack (RFC 0003) runnable. When this facet is present, the host implements RFC 0003 `installAgents`: it loads each installed pack's `agents[]` into an in-process AgentRegistry, resolves `systemPromptRef` + `handoff.*SchemaRef` from the tarball at install (RFC 0003 §C/§D), and can DISPATCH a manifest agent on the existing `core.dispatch`/orchestrator loop (RFC 0007/0037/0061). Does NOT imply swarm/consensus (`host.agentRuntime`), long-term memory (`agents.memoryBackends`), or crews beyond `agents.dispatch`. A host advertising `agentRuntime` is treated as also satisfying this facet (host-services.md §agentRuntime). Its inventory is `GET /agents` (`agent-inventory-response.schema.json`). Hosts that omit this block do not instantiate manifest agents (today's default).",
|
|
88
|
+
"additionalProperties": false,
|
|
89
|
+
"properties": {
|
|
90
|
+
"handoffValidation": {
|
|
91
|
+
"type": "boolean",
|
|
92
|
+
"default": false,
|
|
93
|
+
"description": "When `true`, the host validates inbound task payloads against the agent's `handoff.taskSchemaRef` before dispatch and outbound results against `handoff.returnSchemaRef` before persistence (RFC 0003 §D). When `false`/absent, manifests carrying `handoff` schemas are dispatched with opaque payloads."
|
|
94
|
+
},
|
|
95
|
+
"installScope": {
|
|
96
|
+
"type": "string",
|
|
97
|
+
"enum": [
|
|
98
|
+
"host",
|
|
99
|
+
"tenant"
|
|
100
|
+
],
|
|
101
|
+
"default": "host",
|
|
102
|
+
"description": "RFC 0074. Scope at which manifest agents are installed/approved and therefore enumerated by GET /agents. 'host' (default): a single host-global inventory; the endpoint returns the same set for every caller (RFC 0072's original behavior). 'tenant': agents are installed per tenant·workspace (RFC 0048 owner triple); GET /agents returns ONLY the agents available to the authenticated principal's workspace, and an unapproved/unknown agent 404s — the surface never discloses another tenant's inventory. Does not change dispatch (RFC 0072 §B, owner-triple-scoped POST /runs) or any floor safety guarantee (toolAllowlist/systemPromptRef/SR-1 stay mandatory regardless of scope)."
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
"liveRuntime": {
|
|
107
|
+
"type": "object",
|
|
108
|
+
"description": "RFC 0077. The host executes manifest agents against LIVE models and tools (not the deterministic `manifestRuntime` floor) and emits the content-free `agent.invocation-started` / `agent.invocation-completed` bracket around the `agent.*` family. REQUIRES `manifestRuntime`, of which it is a strict superset. A live invocation MUST perform, in this order: (1) model selection: resolve the manifest's `modelClass` to a concrete model and provider, host-defined but stable within a run (it enters the replay invocation key); a run-time `configurable.ai` override MAY take precedence, and resolution MAY happen downstream, so `agent.invocation-started` MAY omit the resolved model; (2) prompt resolution: `systemPrompt` or `systemPromptRef` wins over `promptOverrides` / `promptLibraryRef` (host-services.md §prompts), and the host MUST emit `agent.prompt-resolved` naming the resolved prompt refs, content-free; (3) tool surface: filter against `toolAllowlist` — a tool outside it MUST NOT be callable; under `toolHooks`, per-tool authorization MUST fail closed (`forbidden`) and tool calls MUST emit `agent.tool-called` / `agent.tool-returned`; (4) memory binding: bind the `memoryShape` backends; under `memoryShape.longTerm` the host MUST redact writes as for any memory write, and MAY emit `memory.written` or consolidate; memory is tenant-scoped; (5) the reasoning and tool turn(s), emitting `agent.reasoned`, `agent.reasoning-delta`, `agent.tool-called` and `agent.tool-returned`. Single-shot is the floor: a host MAY run one turn, and the multi-turn loop (`multiAgent` level 5) composes above it, so loop infrastructure is not required to advertise `liveRuntime`; (6) handoff validation: under `handoff.taskSchemaRef` the host MUST validate the inbound task before step 5 and reject a non-conforming one (see `structuredOutput` for the result); a cross-agent handoff emits `agent.handoff`; (7) confidence escalation, under `confidenceEscalation`; (8) terminal projection onto the run's normal result surface — under `subRunAttestation` the attestation composes unchanged and follows the agent-scoped terminal — and the host MUST emit `agent.invocation-completed` as the final agent-scoped event. Live execution MUST NOT relax the floor. These hold unconditionally: `toolAllowlist` enforcement; inbound `taskSchemaRef` validation when present; tenant scoping of memory and of any enqueued run; treating live model output as untrusted per the envelope contract (a refusal terminates with `outcome: refused`, never a silent substitution); and fail-closed per-tool authorization under `toolHooks`. `structuredOutput` and `confidenceEscalation` are optional quality flags. Hosts that omit this block run the floor only.",
|
|
109
|
+
"additionalProperties": false,
|
|
110
|
+
"properties": {
|
|
111
|
+
"structuredOutput": {
|
|
112
|
+
"type": "boolean",
|
|
113
|
+
"description": "When `true`, the host validates the terminal result against the agent's `handoff.returnSchemaRef` and fails the run with a structured-output error on a non-conforming result rather than shipping it. Absent ⇒ `false` (runs live but does not enforce `returnSchemaRef`)."
|
|
114
|
+
},
|
|
115
|
+
"confidenceEscalation": {
|
|
116
|
+
"type": "boolean",
|
|
117
|
+
"description": "When `true`, the host honors `AgentManifest.confidence.defaultThreshold` and triggers the RFC 0002 §F escalation contract when an `agent.decided` confidence falls below the effective threshold, rather than silently accepting the decision. Absent ⇒ `false`. The effective threshold is `confidence.defaultThreshold`, else the run-resolved threshold, default 0.7; such an `agent.decided` MUST trigger escalation rather than be silently accepted. It is distinct from, and not interchangeable with, the fixed 0.5 `OrchestratorDecision.confidence` floor of `multiAgent` level 2."
|
|
118
|
+
},
|
|
119
|
+
"sources": {
|
|
120
|
+
"type": "array",
|
|
121
|
+
"uniqueItems": true,
|
|
122
|
+
"items": {
|
|
123
|
+
"type": "string",
|
|
124
|
+
"enum": [
|
|
125
|
+
"workflow-node",
|
|
126
|
+
"run-api",
|
|
127
|
+
"chat-mention"
|
|
128
|
+
]
|
|
129
|
+
},
|
|
130
|
+
"description": "Which invocation entry points the host exposes for live manifest dispatch. `workflow-node`: an agent step inside a workflow run (RFC 0072 §B); `run-api`: an agent as the root of POST /runs; `chat-mention`: a chat @agent invocation mapped onto the run surface. Enum membership is NOT mandatory — a host with no chat surface simply omits `chat-mention`. Absent ⇒ `['workflow-node']` (the RFC 0072 §B normative path). All advertised sources MUST emit the identical `agent.invocation.*` + `agent.*` event family. Every source MUST resolve to the same manifest-to-run mapping. A host advertising `run-api` MUST accept a run whose root references a manifest `agentId`; one advertising `chat-mention` MUST map it onto the same run surface. `workflow-node` invocations are node executions inheriting the run's replay, fork and observability envelope."
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
"evalSuite": {
|
|
135
|
+
"type": "object",
|
|
136
|
+
"description": "RFC 0081. The host runs portable `agent-eval-suite.schema.json` suites as eval runs (`mode: eval` on `createRun`, runs.md) and terminates each with an `eval-summary.schema.json` scorecard as the run's output. Hosts that omit this block reject `mode: eval` (runs.md). A host advertising this MUST execute each task as a child agent invocation, reusing the `agent.invocation-*` bracket and the `agent.*` and `provider.usage` events, score it, and MUST emit exactly one `eval.started`, one `eval.scored` per task after that task's terminal `agent.decided`, and one `eval.completed` before `run.completed`. When a task carries `fixtures`, the host MUST inject `fixtures.toolResponses` in place of live tool calls and seed `fixtures.memorySeed` into the agent's read snapshot before the invocation; `live-shadow` alone ignores fixtures. Seeded memory is tenant-scoped and redacted like any memory write. The `eval.*` events and the summary are content-free (SECURITY invariant `eval-summary-no-content-leak`) and are recorded facts: a replay re-reads a score, never re-judges. An eval run, its suite, fixtures and summary are scoped to the caller's owner triple; a suite or summary MUST NOT be readable across tenants. A human MAY override an auto-score with an annotation on its `eval.scored` event. Composes per-task cost (`provider.usage`) and the regression baseline diff.",
|
|
137
|
+
"additionalProperties": false,
|
|
138
|
+
"properties": {
|
|
139
|
+
"modes": {
|
|
140
|
+
"type": "array",
|
|
141
|
+
"uniqueItems": true,
|
|
142
|
+
"items": {
|
|
143
|
+
"type": "string",
|
|
144
|
+
"enum": [
|
|
145
|
+
"golden",
|
|
146
|
+
"rubric",
|
|
147
|
+
"adversarial",
|
|
148
|
+
"regression",
|
|
149
|
+
"live-shadow"
|
|
150
|
+
]
|
|
151
|
+
},
|
|
152
|
+
"description": "Which eval modes the host actually implements (RFC 0081 §D closed vocabulary). Truthful advertisement (RFC 0031): a host advertises ONLY the modes it gates on; a suite requesting an unadvertised mode is rejected at run-create with `400 validation_error`, as is one requesting a mode the suite does not declare. Absent ⇒ no modes (the host advertises the family but gates nothing — effectively shape-only)."
|
|
153
|
+
},
|
|
154
|
+
"maxTasksPerSuite": {
|
|
155
|
+
"type": "integer",
|
|
156
|
+
"minimum": 1,
|
|
157
|
+
"description": "MAY. Host ceiling on tasks per suite; a suite exceeding it is rejected at run-create (the RFC 0058 §A clamp pattern)."
|
|
158
|
+
},
|
|
159
|
+
"maxCostUsdPerSuite": {
|
|
160
|
+
"type": "number",
|
|
161
|
+
"minimum": 0,
|
|
162
|
+
"description": "MAY. Host ceiling on total eval-run cost; composes RFC 0084 budget enforcement when advertised."
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
"deployment": {
|
|
167
|
+
"type": "object",
|
|
168
|
+
"description": "RFC 0082. The host implements an agent deployment lifecycle: per-(agentId, version) deployment records with the seven-state machine (draft/test/staged/active/paused/deprecated/rolled-back), named-channel binding (`agentId@channel` / `@latest` resolved + pinned per-(run, agentId, channel) at first resolution per §B), optional canary traffic-split, a rollback pointer, the content-free `deployment.*` audit events, and the `POST /agents/{agentId}/deployments` promotion contract composing RFC 0049 (`deploy:*` fail-closed scopes) + RFC 0051 (approvalGate) + RFC 0081 (`requiredEval`). A ref binds by at most one of an exact `version`, a `channel`, or neither (host default); both is a `validation_error`. At the first resolution of an `(agentId, channel)` pair in a run the host MUST resolve it to a concrete version; every later resolution of that pair in the run MUST return the same version, and the host MUST NOT re-resolve a channel that moved mid-run. The version is recorded on `agent.invocation-started.resolvedAgentVersion` (with `resolvedChannel`); replay and fork MUST re-read it and MUST NOT re-resolve. With more than one `active` version on a channel, the canary draw is part of that first resolution and MUST NOT be re-rolled on replay. A channel with no `active` version fails closed, never falling back to an arbitrary version (`agent-ref.schema.json#/properties/channel`). A transition (`agent-deployment-transition.schema.json`) MUST be authorized fail-closed against a `deploy:*` scope, emitting `authorization.decided`; runs the approval gate when host policy gates it; and, when the gate carries `requiredEval: { evalRunId, requiredPassScore? }`, MUST verify that eval run is terminal and passed (or meets `requiredPassScore`) before emitting `deployment.promoted`, else denies with `eval_gate_unmet`. A host without `evalSuite` MAY promote without an eval gate. The `deployment.*` events appear on the deployment-management run, never on a consuming run. Channels are tenant-scoped as `manifestRuntime.installScope` scopes agents. Hosts that omit this block reject a `channel`-bearing `AgentRef` with `validation_error`, and the deployment endpoint answers `404 not_found`. The promotion endpoint + behavioral lifecycle scenario + reference-host store land at Active → Accepted.",
|
|
169
|
+
"additionalProperties": false,
|
|
170
|
+
"properties": {
|
|
171
|
+
"channels": {
|
|
172
|
+
"type": "array",
|
|
173
|
+
"uniqueItems": true,
|
|
174
|
+
"items": {
|
|
175
|
+
"type": "string",
|
|
176
|
+
"minLength": 1
|
|
177
|
+
},
|
|
178
|
+
"description": "The named channels the host resolves (e.g. `[\"stable\", \"canary\", \"latest\"]`). Truthful advertisement (RFC 0031): a `channel` not in this list resolves to no version and fails the run with `not_found` (`details.service: agents`)."
|
|
179
|
+
},
|
|
180
|
+
"canary": {
|
|
181
|
+
"type": "boolean",
|
|
182
|
+
"description": "When `true`, the host implements canary traffic-split (a per-run §B draw assigns the run to one of the channel's active versions by `canaryPercent`). When `false`/absent, the host MUST reject any `canaryPercent < 100`."
|
|
183
|
+
},
|
|
184
|
+
"rollback": {
|
|
185
|
+
"type": "boolean",
|
|
186
|
+
"description": "When `true`, the host implements the `rollbackPointer` recovery path (active→rolled-back restoring a prior version to active)."
|
|
187
|
+
},
|
|
188
|
+
"states": {
|
|
189
|
+
"type": "array",
|
|
190
|
+
"uniqueItems": true,
|
|
191
|
+
"items": {
|
|
192
|
+
"type": "string",
|
|
193
|
+
"enum": [
|
|
194
|
+
"draft",
|
|
195
|
+
"test",
|
|
196
|
+
"staged",
|
|
197
|
+
"active",
|
|
198
|
+
"paused",
|
|
199
|
+
"deprecated",
|
|
200
|
+
"rolled-back"
|
|
201
|
+
]
|
|
202
|
+
},
|
|
203
|
+
"description": "The subset of the seven lifecycle states the host implements. Truthful advertisement (RFC 0031): the host MUST reject a transition into a state not advertised here. A host implementing a subset MUST advertise exactly that subset."
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
"roster": {
|
|
208
|
+
"type": "object",
|
|
209
|
+
"description": "RFC 0086. The host maintains a standing agent roster: named, tenant-scoped agent INSTANCES (the 'digital-twin employee') that reference a manifest/deployment and own a workflow portfolio, discoverable via GET /agents/roster, with trigger-fired portfolio runs attributed to the member via the content-free `roster.run.initiated` event. `rosterId` MUST be a `host:<id>` form; dispatching it (a `WorkflowNode.agent` or a run against it) MUST resolve to the entry's bound `agentRef`, MUST project its `persona` onto the dispatch `AgentRef`, and MUST emit `roster.run-initiated`. An entry MUST NOT list a workflow outside its owner's tenant scope. `enabled: false` makes an entry's portfolio triggers inert without deleting it; a disabled entry SHOULD remain discoverable. `GET /agents/roster` and `GET /agents/roster/{rosterId}` MUST be tenant-scoped as `GET /agents` is: an entry outside the caller's owner triple MUST answer `404`. When a trigger fires a workflow in an entry's portfolio, the host MUST emit one `roster.run-initiated` immediately after `run.started` and before any agent invocation. REQUIRES `agents.manifestRuntime` (a roster entry instantiates a manifest agent). Triggers compose RFC 0052 (schedule) + RFC 0083 (durable work-item bridge) — no new WorkflowTrigger.type; the concrete work surface (a Kanban board) stays a host/vendor extension (it participates by bridging a work-item event into a trigger delivery). Hosts that omit this block do not maintain a roster (the roster read answers `404 not_found`). The roster-management endpoints + behavioral attribution scenario + reference-host store land at Active → Accepted.",
|
|
210
|
+
"additionalProperties": false,
|
|
211
|
+
"properties": {
|
|
212
|
+
"installScope": {
|
|
213
|
+
"type": "string",
|
|
214
|
+
"enum": [
|
|
215
|
+
"host",
|
|
216
|
+
"tenant"
|
|
217
|
+
],
|
|
218
|
+
"description": "RFC 0074 carry-forward. `host`: a single global roster. `tenant`: roster entries are scoped per owner triple; GET /agents/roster returns only the caller's entries and a cross-tenant entry 404s. MUST equal `agents.manifestRuntime.installScope` (a roster cannot be host-global while its manifests are tenant-scoped, or vice-versa)."
|
|
219
|
+
},
|
|
220
|
+
"portfolioTriggerSources": {
|
|
221
|
+
"type": "array",
|
|
222
|
+
"uniqueItems": true,
|
|
223
|
+
"items": {
|
|
224
|
+
"type": "string",
|
|
225
|
+
"minLength": 1
|
|
226
|
+
},
|
|
227
|
+
"description": "Which RFC 0052/0083 trigger sources fire portfolio runs on this host (e.g. `[\"schedule\", \"queue\", \"webhook\"]`). Truthful advertisement (RFC 0031): a source not listed does not fire portfolios here."
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
"orgChart": {
|
|
232
|
+
"type": "object",
|
|
233
|
+
"description": "RFC 0087. The host maintains a tenant-scoped, DESCRIPTIVE org-chart over RFC 0086 roster members: departments + roles with acyclic `reportsTo` edges + a derived responsibility roll-up, discoverable via GET /agents/org-chart. The load-bearing guarantee (§B `org-position-no-authority-escalation`): an org edge confers NO authority — it MUST NOT widen `toolAllowlist` (RFC 0002 §A14), grant an RBAC scope (RFC 0049), or bypass an approval gate (RFC 0051); org position MUST NOT be an authorization input. The schema carries no authority-bearing field, and a conformant host MUST NOT derive authority from position out-of-band. `members[].rosterId` MUST reference a roster entry in the same owner triple (a cross-tenant member is a `validation_error`), and the `reportsTo` edges MUST be acyclic (a cycle is a `validation_error`). On a `tenant` host the chart reads return only the caller's chart, never disclosing an outside member, department or edge, and an unknown or cross-tenant `departmentId` answers `404`. Being a manager MUST NOT add a report's tools, nor may a report inherit a manager's; position MUST NOT cause an `authorization.decided { allowed: true }` the principal's scopes alone would not; being senior MUST NOT satisfy, bypass or override an approval gate. A host MAY use position for non-authority purposes (rendering, routing preference, notification, responsibility reporting). The non-authority rule holds at every `installScope` and is never opt-out. REQUIRES `agents.roster` (the chart's members are roster entries). Hosts that omit this block have no org-chart surface (the read answers `404 not_found`). The org-chart-management endpoints + behavioral non-authority scenario + reference-host store land at Active → Accepted.",
|
|
234
|
+
"additionalProperties": false,
|
|
235
|
+
"properties": {
|
|
236
|
+
"installScope": {
|
|
237
|
+
"type": "string",
|
|
238
|
+
"enum": [
|
|
239
|
+
"host",
|
|
240
|
+
"tenant"
|
|
241
|
+
],
|
|
242
|
+
"description": "RFC 0074 carry-forward. `host`: a single global chart. `tenant`: charts are scoped per owner triple; GET /agents/org-chart returns only the caller's chart. SHOULD equal `agents.roster.installScope` (the members are roster entries)."
|
|
243
|
+
},
|
|
244
|
+
"departmentNesting": {
|
|
245
|
+
"type": "boolean",
|
|
246
|
+
"description": "When `true`, the host supports `parentDepartmentId` trees. When `false`/absent, the host MUST reject a non-null `parentDepartmentId` (truthful advertisement, RFC 0031)."
|
|
247
|
+
},
|
|
248
|
+
"responsibilityView": {
|
|
249
|
+
"type": "boolean",
|
|
250
|
+
"description": "When `true`, the host computes the responsibility roll-up on `GET /agents/org-chart/{departmentId}`: the union of the department's members' `workflows[]` portfolios, recursively through sub-departments unless `recursive=false`. A view computed from roster entries: it grants nothing and stores nothing."
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
"dispatchMapping": {
|
|
255
|
+
"type": "boolean",
|
|
256
|
+
"default": false,
|
|
257
|
+
"description": "RFC 0022. When `true`, the host honors `inputMapping` / `outputMapping` / `perWorkerInputMappings` / `perWorkerOutputMappings` on `DispatchConfig` — building child inputs from parent variables before dispatch and harvesting child variables into parent variables on completion. Implies (but does NOT require) `agents.dispatch: true`. Hosts that set `agents.dispatch: true` but omit / `false` this flag MUST refuse workflows that carry non-empty mapping fields at registration with `validation_error` + `details.requiredCapability: 'agents.dispatchMapping'`."
|
|
258
|
+
},
|
|
259
|
+
"reasoning": {
|
|
260
|
+
"type": "object",
|
|
261
|
+
"description": "Reasoning-event verbosity configuration.",
|
|
262
|
+
"properties": {
|
|
263
|
+
"verbosity": {
|
|
264
|
+
"type": "string",
|
|
265
|
+
"enum": [
|
|
266
|
+
"summary",
|
|
267
|
+
"full",
|
|
268
|
+
"off"
|
|
269
|
+
],
|
|
270
|
+
"description": "Default reasoning verbosity for `agent.reasoned` events when the run does not override via `RunOptions.configurable.reasoningVerbosity`. `summary`: the host SHOULD bound each `agent.reasoned` `reasoning` to `tokenLimit` tokens. `full`: the host MAY emit complete model traces. `off`: the host suppresses `agent.reasoned`. A run MAY override the default."
|
|
271
|
+
},
|
|
272
|
+
"tokenLimit": {
|
|
273
|
+
"type": "integer",
|
|
274
|
+
"minimum": 0,
|
|
275
|
+
"description": "Effective cap on reasoning trace length when verbosity is `summary`. Default 512 tokens."
|
|
276
|
+
},
|
|
277
|
+
"streaming": {
|
|
278
|
+
"type": "boolean",
|
|
279
|
+
"default": false,
|
|
280
|
+
"description": "RFC 0024. When `true`, the host MAY emit `agent.reasoning-delta` events while a reasoning block is still open, in addition to the final `agent.reasoned`. Hosts that omit / `false` this flag emit only the final `agent.reasoned`. Consumers MUST tolerate both modes. A streaming host emits zero or more deltas followed by exactly one closing `agent.reasoned`, which stays authoritative for the reasoning content."
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
"additionalProperties": false
|
|
284
|
+
},
|
|
285
|
+
"subRunAttestation": {
|
|
286
|
+
"type": "boolean",
|
|
287
|
+
"default": false,
|
|
288
|
+
"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)."
|
|
289
|
+
},
|
|
290
|
+
"proposals": {
|
|
291
|
+
"type": "object",
|
|
292
|
+
"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. v2 defines no protocol path for the proposal surface. A host advertising this 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. The redaction-safety of `rationale` and `provenance.sourceRunIds` and the lifecycle are in `proposal.schema.json`.",
|
|
293
|
+
"additionalProperties": false,
|
|
294
|
+
"required": [
|
|
295
|
+
"artifactKinds",
|
|
296
|
+
"activation"
|
|
297
|
+
],
|
|
298
|
+
"properties": {
|
|
299
|
+
"artifactKinds": {
|
|
300
|
+
"type": "array",
|
|
301
|
+
"items": {
|
|
302
|
+
"type": "string",
|
|
303
|
+
"enum": [
|
|
304
|
+
"agent-pack",
|
|
305
|
+
"workflow-chain-pack",
|
|
306
|
+
"prompt-template",
|
|
307
|
+
"automation"
|
|
308
|
+
]
|
|
309
|
+
},
|
|
310
|
+
"uniqueItems": true,
|
|
311
|
+
"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)."
|
|
312
|
+
},
|
|
313
|
+
"duplicationDetection": {
|
|
314
|
+
"type": "boolean",
|
|
315
|
+
"default": false,
|
|
316
|
+
"description": "When `true`, the host populates `Proposal.duplicateOf` with an existing artifact ref the proposal restates/overlaps (the 'Curator' duplication signal)."
|
|
317
|
+
},
|
|
318
|
+
"activation": {
|
|
319
|
+
"type": "string",
|
|
320
|
+
"enum": [
|
|
321
|
+
"approval-gate",
|
|
322
|
+
"direct-rbac"
|
|
323
|
+
],
|
|
324
|
+
"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. An `overridden` gate MUST be audited."
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
"goals": {
|
|
329
|
+
"type": "object",
|
|
330
|
+
"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). v2 defines no protocol path for the goal surface. A host advertising this 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. When the agent raises a confidence-escalation interrupt against a goal, the host MUST set `state: escalated` and stop continuation until a human resolves it. Each judge evaluation MUST be attributable to the run it evaluated (`goal.evaluated.runId`); its verdict MUST be recorded on `goal.evaluated` and MUST NOT be recomputed on replay or fork. `objective` and any verdict payload MUST be redaction-safe. Hosts that omit this block do not run standing goals; the conformance scenarios skip cleanly.",
|
|
331
|
+
"additionalProperties": false,
|
|
332
|
+
"required": [
|
|
333
|
+
"judge",
|
|
334
|
+
"continuation"
|
|
335
|
+
],
|
|
336
|
+
"properties": {
|
|
337
|
+
"judge": {
|
|
338
|
+
"type": "string",
|
|
339
|
+
"enum": [
|
|
340
|
+
"verifier",
|
|
341
|
+
"host"
|
|
342
|
+
],
|
|
343
|
+
"description": "`verifier`: completion is an RFC 0090 verifier verdict. `host`: an opaque host evaluator."
|
|
344
|
+
},
|
|
345
|
+
"continuation": {
|
|
346
|
+
"type": "array",
|
|
347
|
+
"items": {
|
|
348
|
+
"type": "string",
|
|
349
|
+
"enum": [
|
|
350
|
+
"schedule",
|
|
351
|
+
"commitment",
|
|
352
|
+
"heartbeat",
|
|
353
|
+
"manual"
|
|
354
|
+
]
|
|
355
|
+
},
|
|
356
|
+
"uniqueItems": true,
|
|
357
|
+
"description": "How a goal re-engages work between judge checks. `schedule` (RFC 0052), `commitment` (RFC 0068), `heartbeat` (RFC 0060), `manual`."
|
|
358
|
+
},
|
|
359
|
+
"requiresBounds": {
|
|
360
|
+
"type": "boolean",
|
|
361
|
+
"default": true,
|
|
362
|
+
"description": "When `true` (default), a goal MUST declare valid RFC 0058 `bounds` before it may activate; a goal create without bounds is refused with `422`. The host MUST stop continuation and set `state: bound-exceeded` when any declared bound (iteration count / accumulated cost / wall-clock deadline) is crossed, emitting `goal.closed`."
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"errorCode": {
|
|
75
75
|
"type": "string",
|
|
76
76
|
"minLength": 1,
|
|
77
|
-
"description": "Wire-format error code returned on denial. Defaults to `provider_policy_denied`.
|
|
77
|
+
"description": "Wire-format error code returned on denial. Defaults to `provider_policy_denied`. Any other value MUST be a vendor code."
|
|
78
78
|
}
|
|
79
79
|
},
|
|
80
80
|
"additionalProperties": false
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
"document"
|
|
97
97
|
]
|
|
98
98
|
},
|
|
99
|
-
"description": "Input modalities the host's `callAI` accepts as ContentParts. `text` is implicit even when omitted. A ContentPart whose `type` is not advertised here MUST be rejected with `
|
|
99
|
+
"description": "Input modalities the host's `callAI` accepts as ContentParts. `text` is implicit even when omitted. A ContentPart whose `type` is not advertised here MUST be rejected with `capability_not_provided` (never silently dropped)."
|
|
100
100
|
},
|
|
101
101
|
"maxBytesPerPart": {
|
|
102
102
|
"type": "integer",
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Error codes by HTTP status
|
|
2
|
+
|
|
3
|
+
> **Status: Stable.** Generated from `spec/v2/errors.json` by `scripts/generate-error-envelope.mjs`; do not edit.
|
|
4
|
+
|
|
5
|
+
Every registered code (120 codes), by HTTP status. The registry is normative; this table restates it for reading. `retriable` and `statusSource` are in the registry. The rules are in [errors.md](../core/errors.md).
|
|
6
|
+
|
|
7
|
+
Code | Status
|
|
8
|
+
--- | ---
|
|
9
|
+
`connection_provider_unresolved` | 400
|
|
10
|
+
`connector_action_unresolved` | 400
|
|
11
|
+
`credential_scope_unsupported` | 400
|
|
12
|
+
`delegation_chain_cyclic` | 400
|
|
13
|
+
`delegation_chain_too_long` | 400
|
|
14
|
+
`idempotency_key_invalid` | 400
|
|
15
|
+
`interop_version_unsupported` | 400
|
|
16
|
+
`oauth_provider_unsupported` | 400
|
|
17
|
+
`oauth_scope_unsupported` | 400
|
|
18
|
+
`pack_dependency_cycle` | 400
|
|
19
|
+
`pack_engine_unsupported` | 400
|
|
20
|
+
`pack_integrity_failure` | 400
|
|
21
|
+
`pack_kind_invalid` | 400
|
|
22
|
+
`pack_lockfile_incomplete` | 400
|
|
23
|
+
`pack_peer_dependency_missing` | 400
|
|
24
|
+
`pack_peer_dependency_undefined` | 400
|
|
25
|
+
`pack_signature_invalid` | 400
|
|
26
|
+
`pack_validation_failed` | 400
|
|
27
|
+
`protocol_version_mismatch` | 400
|
|
28
|
+
`schedule_horizon_exceeded` | 400
|
|
29
|
+
`sub_chain_cycle` | 400
|
|
30
|
+
`sub_chain_depth_exceeded` | 400
|
|
31
|
+
`unsupported_runtime` | 400
|
|
32
|
+
`unsupported_stream_mode` | 400
|
|
33
|
+
`until_in_past` | 400
|
|
34
|
+
`validation_error` | 400
|
|
35
|
+
`webhook_endpoint_unverified` | 400
|
|
36
|
+
`webhook_url_rejected` | 400
|
|
37
|
+
`audience_mismatch` | 401
|
|
38
|
+
`connector_auth_declined` | 401
|
|
39
|
+
`connector_auth_expired` | 401
|
|
40
|
+
`credential_lifetime_exceeded` | 401
|
|
41
|
+
`credential_revoked` | 401
|
|
42
|
+
`delegation_expired` | 401
|
|
43
|
+
`identity_unresolvable` | 401
|
|
44
|
+
`identity_unverified` | 401
|
|
45
|
+
`interrupt_token_invalid` | 401
|
|
46
|
+
`key_revoked` | 401
|
|
47
|
+
`sender_constraint_missing` | 401
|
|
48
|
+
`unauthenticated` | 401
|
|
49
|
+
`credential_forbidden` | 403
|
|
50
|
+
`credential_scope_forbidden` | 403
|
|
51
|
+
`delegation_scope_amplified` | 403
|
|
52
|
+
`egress_denied` | 403
|
|
53
|
+
`forbidden` | 403
|
|
54
|
+
`force_engine_version_forbidden` | 403
|
|
55
|
+
`id_tenant_mismatch` | 403
|
|
56
|
+
`mock_provider_forbidden` | 403
|
|
57
|
+
`pack_namespace_unauthorized` | 403
|
|
58
|
+
`run_forbidden` | 403
|
|
59
|
+
`sandbox_capability_denied` | 403
|
|
60
|
+
`sandbox_escape_attempt` | 403
|
|
61
|
+
`workspace_membership_required` | 403
|
|
62
|
+
`credential_not_found` | 404
|
|
63
|
+
`interrupt_not_found` | 404
|
|
64
|
+
`not_found` | 404
|
|
65
|
+
`pack_version_not_found` | 404
|
|
66
|
+
`replay_source_missing` | 404
|
|
67
|
+
`signature_not_available` | 404
|
|
68
|
+
`protocol_version_unsupported` | 406
|
|
69
|
+
`connection_provider_conflict` | 409
|
|
70
|
+
`envelope_correlation_conflict` | 409
|
|
71
|
+
`idempotency_in_flight` | 409
|
|
72
|
+
`idempotency_key_mismatch` | 409
|
|
73
|
+
`interrupt_already_resolved` | 409
|
|
74
|
+
`pack_dependency_conflict` | 409
|
|
75
|
+
`pack_integrity_mismatch` | 409
|
|
76
|
+
`replay_context_summary_unavailable` | 409
|
|
77
|
+
`replay_diverged_at_refusal` | 409
|
|
78
|
+
`replay_memory_snapshot_unavailable` | 409
|
|
79
|
+
`run_already_active` | 409
|
|
80
|
+
`run_state_conflict` | 409
|
|
81
|
+
`run_terminal` | 409
|
|
82
|
+
`version_conflict` | 409
|
|
83
|
+
`workspace_conflict` | 409
|
|
84
|
+
`interrupt_cancelled` | 410
|
|
85
|
+
`interrupt_expired` | 410
|
|
86
|
+
`run_expired` | 410
|
|
87
|
+
`payload_too_large` | 413
|
|
88
|
+
`workspace_too_large` | 413
|
|
89
|
+
`unsupported_media_type` | 415
|
|
90
|
+
`approval_rejected` | 422
|
|
91
|
+
`budget_exhausted` | 422
|
|
92
|
+
`budget_model_denied` | 422
|
|
93
|
+
`capability_not_provided` | 422
|
|
94
|
+
`capability_required` | 422
|
|
95
|
+
`connection_auth_metadata_mismatch` | 422
|
|
96
|
+
`credential_required` | 422
|
|
97
|
+
`envelope_invalid` | 422
|
|
98
|
+
`envelope_refusal` | 422
|
|
99
|
+
`envelope_truncation_unrecoverable` | 422
|
|
100
|
+
`eval_gate_unmet` | 422
|
|
101
|
+
`fork_point_invalid` | 422
|
|
102
|
+
`loop_limit_exceeded` | 422
|
|
103
|
+
`mcp_mrtr_rounds_exceeded` | 422
|
|
104
|
+
`node_config_invalid` | 422
|
|
105
|
+
`pack_runtime_requirement_unmet` | 422
|
|
106
|
+
`provider_policy_denied` | 422
|
|
107
|
+
`recursion_limit_exceeded` | 422
|
|
108
|
+
`residency_unavailable` | 422
|
|
109
|
+
`run_timeout` | 422
|
|
110
|
+
`sandbox_invocation_error` | 422
|
|
111
|
+
`sandbox_memory_exceeded` | 422
|
|
112
|
+
`sandbox_timeout` | 422
|
|
113
|
+
`storage_limit_exceeded` | 422
|
|
114
|
+
`token_budget_exceeded` | 422
|
|
115
|
+
`unknown_envelope_kind` | 422
|
|
116
|
+
`unknown_schema_version` | 422
|
|
117
|
+
`client_version_unsupported` | 426
|
|
118
|
+
`rate_limited` | 429
|
|
119
|
+
`event_type_unmapped` | 500
|
|
120
|
+
`internal_error` | 500
|
|
121
|
+
`pack_load_failure` | 500
|
|
122
|
+
`payload_unprojectable` | 500
|
|
123
|
+
`credential_unavailable` | 501
|
|
124
|
+
`mcp_error` | 502
|
|
125
|
+
`upstream_unavailable` | 502
|
|
126
|
+
`pack_registry_unreachable` | 503
|
|
127
|
+
`runner_unavailable` | 503
|
|
128
|
+
`service_unavailable` | 503
|
|
129
|
+
|
|
130
|
+
*Sources: RFCs 0171, 0227.*
|
package/spec/v2/release.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "RFC 0172 §D.1 — the one release identity the v2 artifacts derive from. `version` is the next corpus tag `v<version>` (the publish workflow's coordinated-release tag pattern `v*`; RFC 0172's `openwop/v2.<minor>.<patch>` spelling is amended to this at its flip). api/v2/*.yaml info.version, the suite's 2.x version and @openwop/spec-artifacts read it. Bumped by the release PR that cuts the tag, never by hand elsewhere.",
|
|
3
|
-
"version": "2.44.
|
|
4
|
-
"corpusTag": "v2.44.
|
|
3
|
+
"version": "2.44.7",
|
|
4
|
+
"corpusTag": "v2.44.7",
|
|
5
5
|
"updated": "2026-09-29"
|
|
6
6
|
}
|