@openwop/openwop-conformance 1.6.1 → 1.11.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.
Files changed (200) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +2 -2
  3. package/api/asyncapi.yaml +127 -0
  4. package/api/openapi.yaml +518 -1
  5. package/coverage.md +44 -2
  6. package/fixtures/conformance-run-duration-breach.json +33 -0
  7. package/fixtures/oauth-providers/synthetic.json +38 -0
  8. package/fixtures.md +29 -0
  9. package/package.json +1 -1
  10. package/schemas/README.md +22 -0
  11. package/schemas/agent-deployment-transition.schema.json +49 -0
  12. package/schemas/agent-deployment.schema.json +54 -0
  13. package/schemas/agent-eval-suite.schema.json +140 -0
  14. package/schemas/agent-inventory-response.schema.json +115 -0
  15. package/schemas/agent-manifest.schema.json +5 -0
  16. package/schemas/agent-org-chart.schema.json +82 -0
  17. package/schemas/agent-ref.schema.json +12 -2
  18. package/schemas/agent-roster-entry.schema.json +81 -0
  19. package/schemas/agent-roster-response.schema.json +21 -0
  20. package/schemas/ai-envelope.schema.json +28 -0
  21. package/schemas/artifact-type-pack-manifest.schema.json +160 -0
  22. package/schemas/budget-policy.schema.json +18 -0
  23. package/schemas/capabilities.schema.json +448 -4
  24. package/schemas/chat-card-pack-manifest.schema.json +158 -0
  25. package/schemas/credential-provenance.schema.json +18 -0
  26. package/schemas/envelopes/media.audio.schema.json +38 -0
  27. package/schemas/envelopes/media.file.schema.json +37 -0
  28. package/schemas/envelopes/media.image.schema.json +33 -0
  29. package/schemas/eval-summary.schema.json +92 -0
  30. package/schemas/heartbeat-evaluated.schema.json +14 -0
  31. package/schemas/heartbeat-state-changed.schema.json +14 -0
  32. package/schemas/node-pack-manifest.schema.json +33 -1
  33. package/schemas/org-chart-responsibility-view.schema.json +26 -0
  34. package/schemas/run-event-payloads.schema.json +380 -6
  35. package/schemas/run-event.schema.json +23 -0
  36. package/schemas/tool-descriptor.schema.json +63 -0
  37. package/schemas/trigger-subscription.schema.json +26 -0
  38. package/schemas/workflow-definition.schema.json +5 -0
  39. package/schemas/workspace-file-create.schema.json +20 -0
  40. package/schemas/workspace-file.schema.json +39 -0
  41. package/src/lib/agentLoop.ts +44 -0
  42. package/src/lib/agentRoster.ts +76 -0
  43. package/src/lib/agentRuntime.ts +45 -0
  44. package/src/lib/artifactTypes.ts +96 -0
  45. package/src/lib/cardPacks.ts +52 -0
  46. package/src/lib/discovery-capabilities.ts +50 -0
  47. package/src/lib/distillation.ts +38 -0
  48. package/src/lib/feedback.ts +3 -3
  49. package/src/lib/heartbeat.ts +31 -0
  50. package/src/lib/liveRuntime.ts +59 -0
  51. package/src/lib/memoryAttribution.ts +48 -0
  52. package/src/lib/profiles.ts +157 -0
  53. package/src/lib/runtimeRequires.ts +38 -0
  54. package/src/lib/safeFetch.ts +87 -0
  55. package/src/lib/subRunAttestation.ts +35 -0
  56. package/src/lib/toolHooks.ts +33 -0
  57. package/src/scenarios/agent-deployment-shape.test.ts +139 -0
  58. package/src/scenarios/agent-eval-suite-shape.test.ts +167 -0
  59. package/src/scenarios/agent-live-allowlist-enforced.test.ts +53 -0
  60. package/src/scenarios/agent-live-invocation-bracket.test.ts +98 -0
  61. package/src/scenarios/agent-live-runtime-shape.test.ts +98 -0
  62. package/src/scenarios/agent-live-structured-output.test.ts +58 -0
  63. package/src/scenarios/agent-loop-iteration-monotonic.test.ts +33 -0
  64. package/src/scenarios/agent-loop-stateful-resume.test.ts +28 -0
  65. package/src/scenarios/agent-loop-version5-shape.test.ts +41 -0
  66. package/src/scenarios/agent-loop-workspace-snapshot.test.ts +33 -0
  67. package/src/scenarios/agent-manifest-runtime.test.ts +85 -0
  68. package/src/scenarios/agent-org-chart-shape.test.ts +127 -0
  69. package/src/scenarios/agent-platform-profile.test.ts +158 -0
  70. package/src/scenarios/agent-roster-attribution.test.ts +179 -0
  71. package/src/scenarios/agent-roster-shape.test.ts +146 -0
  72. package/src/scenarios/ai-envelope-shape.test.ts +14 -18
  73. package/src/scenarios/aiEnvelope.capBreached.test.ts +2 -1
  74. package/src/scenarios/aiEnvelope.schemaDrift.test.ts +2 -1
  75. package/src/scenarios/aiEnvelope.universalKinds.test.ts +2 -1
  76. package/src/scenarios/approval-gate-flow.test.ts +4 -6
  77. package/src/scenarios/artifact-schema-compile-bounded.test.ts +126 -0
  78. package/src/scenarios/artifact-type-pack-install.test.ts +78 -0
  79. package/src/scenarios/artifact-type-pack-manifest-validation.test.ts +140 -0
  80. package/src/scenarios/artifact-type-store-without-render.test.ts +54 -0
  81. package/src/scenarios/audit-log-integrity.test.ts +3 -2
  82. package/src/scenarios/auth-api-key-rotation.test.ts +2 -1
  83. package/src/scenarios/auth-mtls.test.ts +2 -1
  84. package/src/scenarios/auth-oauth2-client-credentials.test.ts +2 -1
  85. package/src/scenarios/auth-oidc-user-bearer.test.ts +2 -1
  86. package/src/scenarios/auth-saml-profile.test.ts +2 -1
  87. package/src/scenarios/auth-scim-profile.test.ts +2 -1
  88. package/src/scenarios/authorization-fail-closed.test.ts +2 -1
  89. package/src/scenarios/authorization-roles-shape.test.ts +2 -1
  90. package/src/scenarios/budget-policy-shape.test.ts +136 -0
  91. package/src/scenarios/byok-auth-modes.test.ts +141 -0
  92. package/src/scenarios/chat-card-pack-execution.test.ts +56 -0
  93. package/src/scenarios/chat-card-pack-manifest-validation.test.ts +128 -0
  94. package/src/scenarios/commitment-fired.test.ts +83 -0
  95. package/src/scenarios/credential-payload-redaction.test.ts +2 -1
  96. package/src/scenarios/credentials-capability-shape.test.ts +2 -1
  97. package/src/scenarios/cross-engine-append-ordering.test.ts +2 -1
  98. package/src/scenarios/cross-host-ancestry-endpoint.test.ts +3 -2
  99. package/src/scenarios/cross-host-causation-shape.test.ts +3 -2
  100. package/src/scenarios/deadletter-capability-shape.test.ts +2 -1
  101. package/src/scenarios/deadletter-retry-exhaustion.test.ts +2 -1
  102. package/src/scenarios/distillation-index-roundtrip.test.ts +35 -0
  103. package/src/scenarios/distillation-secret-carryforward.test.ts +35 -0
  104. package/src/scenarios/distillation-shape.test.ts +41 -0
  105. package/src/scenarios/distillation-stable-archive.test.ts +37 -0
  106. package/src/scenarios/distillation-token-budget.test.ts +45 -0
  107. package/src/scenarios/egress-provenance-shape.test.ts +137 -0
  108. package/src/scenarios/envelope-completion-distinguishes-truncation.test.ts +4 -3
  109. package/src/scenarios/envelope-reasoning-secret-redaction.test.ts +5 -4
  110. package/src/scenarios/envelope-reasoning-shape.test.ts +3 -2
  111. package/src/scenarios/envelope-refusal-shape.test.ts +3 -2
  112. package/src/scenarios/envelope-rendering-hint.test.ts +95 -0
  113. package/src/scenarios/envelope-retry-attempted.test.ts +2 -1
  114. package/src/scenarios/envelope-tier-one-subset-static.test.ts +3 -2
  115. package/src/scenarios/exec-not-protocol-tier.test.ts +137 -0
  116. package/src/scenarios/experimental-tier-shape.test.ts +5 -4
  117. package/src/scenarios/fs-path-traversal.test.ts +2 -1
  118. package/src/scenarios/heartbeat-capability-shape.test.ts +35 -0
  119. package/src/scenarios/heartbeat-fires-once-per-tick.test.ts +28 -0
  120. package/src/scenarios/heartbeat-idempotent-no-spam.test.ts +43 -0
  121. package/src/scenarios/heartbeat-runtime-bound.test.ts +30 -0
  122. package/src/scenarios/http-client-ssrf.test.ts +10 -13
  123. package/src/scenarios/mcp-toolcall-redaction.test.ts +3 -2
  124. package/src/scenarios/media-url-inline-cap.test.ts +167 -0
  125. package/src/scenarios/memory-attribution-emits-on-write.test.ts +54 -0
  126. package/src/scenarios/memory-attribution-no-content.test.ts +45 -0
  127. package/src/scenarios/memory-attribution-replay-stable.test.ts +60 -0
  128. package/src/scenarios/memory-attribution-shape.test.ts +28 -0
  129. package/src/scenarios/memory-attribution-tenant-scoped.test.ts +44 -0
  130. package/src/scenarios/memory-capability-model-shape.test.ts +186 -0
  131. package/src/scenarios/memory-compaction-event-emitted.test.ts +2 -1
  132. package/src/scenarios/memory-compaction-provenance-tag.test.ts +2 -1
  133. package/src/scenarios/memory-compaction-sr1-carry-forward.test.ts +2 -1
  134. package/src/scenarios/memory-consolidation-idempotent.test.ts +77 -0
  135. package/src/scenarios/memory-consolidation-shape.test.ts +90 -0
  136. package/src/scenarios/model-capability-substituted.test.ts +2 -1
  137. package/src/scenarios/multi-agent-confidence-escalation.test.ts +5 -4
  138. package/src/scenarios/multi-agent-handoff-state-machine.test.ts +6 -5
  139. package/src/scenarios/multi-agent-memory-lifecycle.test.ts +4 -3
  140. package/src/scenarios/multi-region-idempotency.test.ts +10 -10
  141. package/src/scenarios/oauth-authorization-code-roundtrip.test.ts +145 -0
  142. package/src/scenarios/oauth-capability-shape.test.ts +2 -1
  143. package/src/scenarios/oauth-connector-redaction.test.ts +2 -1
  144. package/src/scenarios/pause-resume.test.ts +3 -3
  145. package/src/scenarios/production-backpressure.test.ts +2 -2
  146. package/src/scenarios/production-retention-expiry.test.ts +2 -2
  147. package/src/scenarios/prompt-all-four-kinds-events.test.ts +2 -1
  148. package/src/scenarios/prompt-composed-secret-redaction.test.ts +2 -1
  149. package/src/scenarios/prompt-composed-trust-marker.test.ts +2 -1
  150. package/src/scenarios/prompt-end-to-end-events.test.ts +2 -1
  151. package/src/scenarios/prompt-list-and-fetch.test.ts +2 -1
  152. package/src/scenarios/prompt-mutable-lifecycle.test.ts +2 -1
  153. package/src/scenarios/prompt-mutation-workspace-membership-enforced.test.ts +2 -1
  154. package/src/scenarios/prompt-pack-install.test.ts +2 -1
  155. package/src/scenarios/prompt-read-workspace-membership-enforced.test.ts +2 -1
  156. package/src/scenarios/prompt-render-deterministic.test.ts +2 -1
  157. package/src/scenarios/prompt-resolution-chain-agent-intrinsic.test.ts +2 -1
  158. package/src/scenarios/prompt-resolution-chain-fallback-cascade.test.ts +2 -1
  159. package/src/scenarios/prompt-resolution-chain-node-wins.test.ts +2 -1
  160. package/src/scenarios/prompt-template-shape.test.ts +2 -1
  161. package/src/scenarios/provider-usage.test.ts +2 -1
  162. package/src/scenarios/replay-divergence-at-refusal.test.ts +4 -3
  163. package/src/scenarios/replay-fork-arbitrary.test.ts +3 -1
  164. package/src/scenarios/replay-llm-cache-key-portable.test.ts +2 -1
  165. package/src/scenarios/replayDeterminism.test.ts +3 -1
  166. package/src/scenarios/run-execution-bounds-shape.test.ts +133 -0
  167. package/src/scenarios/runtime-requires-install-gate.test.ts +92 -0
  168. package/src/scenarios/runtime-requires-shape.test.ts +134 -0
  169. package/src/scenarios/safefetch-behavior.test.ts +99 -0
  170. package/src/scenarios/safefetch-live-audit.test.ts +175 -0
  171. package/src/scenarios/sandbox-memory-cap.test.ts +2 -1
  172. package/src/scenarios/sandbox-mvp-behavior.test.ts +2 -1
  173. package/src/scenarios/sandbox-no-host-fs-escape.test.ts +2 -1
  174. package/src/scenarios/sandbox-timeout-cap.test.ts +2 -1
  175. package/src/scenarios/scheduling-capability-shape.test.ts +2 -1
  176. package/src/scenarios/scheduling-cron-fires-once.test.ts +2 -1
  177. package/src/scenarios/secret-leakage-otel-attribute.test.ts +7 -6
  178. package/src/scenarios/spec-corpus-validity.test.ts +20 -4
  179. package/src/scenarios/subrun-approval-fail-closed.test.ts +33 -0
  180. package/src/scenarios/subrun-approval-gate.test.ts +35 -0
  181. package/src/scenarios/subrun-attestation-shape.test.ts +30 -0
  182. package/src/scenarios/subrun-checksum-stable.test.ts +43 -0
  183. package/src/scenarios/tool-descriptor-shape.test.ts +133 -0
  184. package/src/scenarios/tool-hooks-authorization-fail-closed.test.ts +39 -0
  185. package/src/scenarios/tool-hooks-content-free.test.ts +40 -0
  186. package/src/scenarios/tool-hooks-rate-limit.test.ts +32 -0
  187. package/src/scenarios/tool-hooks-secret-redaction.test.ts +34 -0
  188. package/src/scenarios/tool-hooks-shape.test.ts +34 -0
  189. package/src/scenarios/trigger-bridge-shape.test.ts +135 -0
  190. package/src/scenarios/wasm-pack-abi-version-rejection.test.ts +3 -10
  191. package/src/scenarios/wasm-pack-invoke-completed.test.ts +2 -2
  192. package/src/scenarios/wasm-pack-invoke-suspended.test.ts +2 -2
  193. package/src/scenarios/wasm-pack-load.test.ts +2 -2
  194. package/src/scenarios/wasm-pack-memory-cap.test.ts +3 -6
  195. package/src/scenarios/wasm-pack-replay-determinism.test.ts +2 -2
  196. package/src/scenarios/workflow-primary-output-annotation.test.ts +142 -0
  197. package/src/scenarios/workspace-behavior.test.ts +134 -0
  198. package/src/scenarios/workspace-capability-shape.test.ts +73 -0
  199. package/src/scenarios/workspace-cross-tenant-isolation.test.ts +84 -0
  200. package/src/scenarios/x-openwop-form-pack-manifest.test.ts +155 -0
@@ -0,0 +1,160 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://openwop.dev/spec/v1/artifact-type-pack-manifest.schema.json",
4
+ "title": "ArtifactTypePackManifest",
5
+ "description": "Manifest for a published OpenWOP artifact-type pack — `pack.json` at the pack root with `kind: \"artifact-type\"`. Peer to `node-pack-manifest.schema.json` (RFC 0003), `workflow-chain-pack-manifest.schema.json` (RFC 0013), and `prompt-pack-manifest.schema.json` (RFC 0028); disjoint from all three via the `kind` discriminator. See `spec/v1/artifact-type-packs.md` for the canonical contract and RFC 0071 for the rationale.\n\nArtifact-type packs distribute typed artifact definitions — the JSON Schema, rendering hint, lifecycle, and export-format hints for the rich outputs workflow nodes produce — via the same signed-tarball + Ed25519 + SRI pipeline that already serves node, workflow-chain, and prompt packs. When a host installs an artifact-type pack and advertises `host.artifactTypes: { supported: true }`, it validates produced artifacts of the declared `artifactTypeId`s against their `schemaRef` before emitting `artifact.created`.",
6
+ "type": "object",
7
+ "required": ["name", "version", "kind", "engines", "artifactTypes"],
8
+ "additionalProperties": false,
9
+ "properties": {
10
+ "kind": {
11
+ "type": "string",
12
+ "const": "artifact-type",
13
+ "description": "Pack kind discriminator. MUST be the literal string `\"artifact-type\"`. Manifests carrying any other `kind` value validate against a different pack-manifest schema."
14
+ },
15
+ "name": {
16
+ "type": "string",
17
+ "description": "Reverse-DNS pack name per `node-packs.md` §Naming. Reserved scopes are identical (`core.*` / `vendor.<org>.*` / `community.<author>.*` / `private.<host>.*`). Mirror of `prompt-pack-manifest.schema.json#/properties/name`.",
18
+ "pattern": "^(core|vendor|community|private)\\.[a-z][a-z0-9_-]*(\\.[a-z][a-zA-Z0-9_-]*)+$",
19
+ "minLength": 1,
20
+ "maxLength": 256
21
+ },
22
+ "version": {
23
+ "type": "string",
24
+ "description": "Pack-level SemVer 2.0.0.",
25
+ "pattern": "^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$"
26
+ },
27
+ "description": { "type": "string", "maxLength": 1024 },
28
+ "author": { "type": "string" },
29
+ "license": { "type": "string", "description": "SPDX license identifier (e.g., `Apache-2.0`, `MIT`)." },
30
+ "homepage": { "type": "string", "format": "uri" },
31
+ "repository": { "type": "string", "format": "uri" },
32
+ "keywords": {
33
+ "type": "array",
34
+ "items": { "type": "string", "maxLength": 64 },
35
+ "maxItems": 50
36
+ },
37
+ "engines": {
38
+ "type": "object",
39
+ "required": ["openwop"],
40
+ "properties": {
41
+ "openwop": {
42
+ "type": "string",
43
+ "description": "Semver range — which openwop protocol versions this pack works against. Example: `>=1.1 <2.0.0`."
44
+ }
45
+ },
46
+ "additionalProperties": true
47
+ },
48
+ "dependencies": {
49
+ "type": "object",
50
+ "additionalProperties": { "type": "string" },
51
+ "description": "Other packs this pack depends on. Map of pack name → semver range. Resolved transitively at workflow-register time."
52
+ },
53
+ "peerDependencies": {
54
+ "type": "object",
55
+ "additionalProperties": { "type": "string" },
56
+ "description": "Engine-supplied capabilities the pack consumes (e.g., `{ \"host.artifactTypes\": \"supported\" }`). Resolved against the host's advertised capabilities at register time."
57
+ },
58
+ "artifactTypes": {
59
+ "type": "array",
60
+ "minItems": 1,
61
+ "items": { "$ref": "#/$defs/ArtifactType" },
62
+ "description": "Typed artifact definitions this pack contributes. Each MUST have a unique `artifactTypeId` within the pack."
63
+ },
64
+ "signing": { "$ref": "#/$defs/Signing" }
65
+ },
66
+ "$defs": {
67
+ "ArtifactType": {
68
+ "type": "object",
69
+ "required": ["artifactTypeId", "schemaRef"],
70
+ "additionalProperties": false,
71
+ "properties": {
72
+ "artifactTypeId": {
73
+ "type": "string",
74
+ "description": "Reverse-DNS artifact-type identifier. Same pattern and reserved scopes as a pack `name`. This is the value `WorkflowNode.artifactType`, `nodes[].artifact.typeId`, and `artifact.created.artifactType` reference. Third parties MUST NOT publish under `core.*`.",
75
+ "pattern": "^(core|vendor|community|private)\\.[a-z][a-z0-9_-]*(\\.[a-z][a-zA-Z0-9_-]*)+$",
76
+ "minLength": 1,
77
+ "maxLength": 256
78
+ },
79
+ "schemaRef": {
80
+ "type": "string",
81
+ "minLength": 1,
82
+ "description": "Path inside the pack tarball to the artifact's JSON Schema (Draft 2020-12). The target schema MUST set `additionalProperties: false` at its top level and declare an `$id` under `{HostBase}/schemas/artifacts/{artifactTypeId}.schema.json`, mirroring the envelope convention in `ai-envelope.md` §\"Canonical schema location\"."
83
+ },
84
+ "schemaVersion": {
85
+ "type": "integer",
86
+ "minimum": 0,
87
+ "description": "Non-negative integer artifact-schema version, parallel to the per-kind integer in `capabilities.schemaVersions`. Absent ⇒ treated as 0. Bumped when the artifact schema changes shape. A version *declaration*, not a validation guarantee (RFC 0075 / P1-2)."
88
+ },
89
+ "validation": {
90
+ "type": "string",
91
+ "enum": ["open", "closed"],
92
+ "description": "RFC 0075. Strictness contract of the artifact's `schemaRef` schema. `closed` ⇒ closed-world (`additionalProperties: false`); a consumer MAY rely on the absence of unknown fields. `open` (recommended for AI/LLM-produced artifacts) ⇒ the schema tolerates extra fields to absorb model drift; consumers MUST ignore unknown fields per COMPATIBILITY.md §2.1. Absent ⇒ `open` (the forward-compatible default). The `additionalProperties:false` requirement on `schemaRef` was relaxed MUST → SHOULD by RFC 0075: a closed-world artifact contract contradicts the protocol's own forward-compat mandate and the first AI-native adopter cannot meet it."
93
+ },
94
+ "displayName": {
95
+ "type": "string",
96
+ "description": "Human-readable label for artifact-management UIs. Non-normative."
97
+ },
98
+ "rendering": { "$ref": "#/$defs/RenderingHint" },
99
+ "exportFormats": {
100
+ "type": "array",
101
+ "items": {
102
+ "type": "string",
103
+ "minLength": 1,
104
+ "maxLength": 64,
105
+ "pattern": "^([a-z][a-z0-9]*|vendor\\.[a-z][a-z0-9-]*\\.[a-z][a-z0-9-]*|x-[a-z][a-z0-9-]*)$"
106
+ },
107
+ "uniqueItems": true,
108
+ "description": "Export-format identifiers (hints) a renderer MAY offer. Spec-reserved core identifiers carry interoperable meaning (the lowercase file-extension / common name): `pdf`, `pptx`, `docx`, `xlsx`, `md`, `html`, `txt`, `csv`, `json`, `png`, `svg`, `jpeg`, `step`, `stl`, `dxf`. Domain-specific formats outside the core set MUST be `vendor.<org>.<format>`- or `x-<format>`-prefixed (mirrors the `requiredModelCapabilities` reserved-core + extension idiom). Advisory: this spec assigns no byte-level production semantics to any identifier — it standardizes the identifier so two hosts agree what `pptx` names, not how the bytes are produced."
109
+ },
110
+ "syncOn": {
111
+ "type": "string",
112
+ "enum": ["completion", "approval", "manual"],
113
+ "description": "When the host registers the artifact as durable. Mirrors `node-pack-manifest.schema.json#/$defs/PackNode/properties/artifact/properties/syncOn`. Default `completion`."
114
+ },
115
+ "supportsCheckpoint": {
116
+ "type": "boolean",
117
+ "description": "True if the artifact participates in checkpoint/resume. Mirrors the `PackNode.artifact.supportsCheckpoint` field."
118
+ },
119
+ "versionable": {
120
+ "type": "boolean",
121
+ "description": "True if the host SHOULD retain prior versions of the artifact. Non-normative storage hint."
122
+ },
123
+ "diffable": {
124
+ "type": "boolean",
125
+ "description": "True if the artifact's schema supports structural diffing (informs run-diff tooling per rest-endpoints.md §:diff). Non-normative."
126
+ }
127
+ }
128
+ },
129
+ "RenderingHint": {
130
+ "type": "object",
131
+ "additionalProperties": false,
132
+ "description": "Advisory rendering hint. Reuses the closed vocabulary defined in ai-envelope.md §\"Rendering hints\" (RFC 0055). Advisory only — consumers MUST degrade gracefully and MUST NOT treat this as a validation input. The `card` display value is reserved for envelopes and is excluded here (durable artifacts are not transient chat cards).",
133
+ "properties": {
134
+ "display": {
135
+ "type": "string",
136
+ "enum": ["markdown", "code", "image", "audio", "file"],
137
+ "description": "How a consumer SHOULD render the artifact when it recognizes the value."
138
+ },
139
+ "mimeType": { "type": "string", "maxLength": 255 },
140
+ "lang": { "type": "string", "maxLength": 64, "description": "Language hint for `display: code`." },
141
+ "alt": { "type": "string", "maxLength": 1024, "description": "Accessibility text for image/audio/file." },
142
+ "title": { "type": "string", "maxLength": 255 }
143
+ }
144
+ },
145
+ "Signing": {
146
+ "type": "object",
147
+ "description": "Optional signing metadata. See node-packs.md §signing.",
148
+ "additionalProperties": false,
149
+ "properties": {
150
+ "publicKeyRef": { "type": "string", "description": "Path inside the tarball to the Ed25519 public key (PEM-encoded)." },
151
+ "signatureRef": { "type": "string", "description": "Path to the detached signature over `pack.json`." },
152
+ "method": {
153
+ "type": "string",
154
+ "enum": ["manual", "sigstore"],
155
+ "description": "Signing method. `manual` uses publicKeyRef + signatureRef; `sigstore` uses a Sigstore bundle at `pack.json.sigstore`."
156
+ }
157
+ }
158
+ }
159
+ }
160
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://openwop.dev/spec/v1/budget-policy.schema.json",
4
+ "title": "BudgetPolicy",
5
+ "description": "RFC 0084 §A. The reserved `budget` run-options key (on `RunOptions.configurable`) — an enforceable per-run SPEND policy. Wall-time + loop-iterations are deliberately NOT here: those are RFC 0058's `runTimeoutMs` / `maxLoopIterations` (the §E orthogonality seam). 0084 governs spend; 0058 governs execution bounds; they share only the `cap.breached` overflow event. Every dimension is optional; an absent dimension is unbounded (host default).",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "maxTokens": { "type": "integer", "minimum": 1, "description": "Total input+output tokens across all `provider.usage` (RFC 0026) in the run." },
10
+ "maxCostUsd": { "type": "number", "minimum": 0, "description": "Total cost summed from `provider.usage` `costEstimateUsd` (host-defined pricing per RFC 0026)." },
11
+ "maxToolCalls": { "type": "integer", "minimum": 1, "description": "Total `agent.toolCalled` events in the run." },
12
+ "maxRetries": { "type": "integer", "minimum": 0, "description": "Ceiling over the cumulative RFC 0009 retry count (node + envelope retries); the run fails when cumulative retries hit it. NOT a separate retry mechanism (RFC 0084 §UQ4)." },
13
+ "modelAllow": { "type": "array", "items": { "type": "string" }, "uniqueItems": true, "description": "Optional allowlist (glob over provider model ids, e.g. `claude-*`). A run resolving to a model outside the allowlist is refused with `budget_model_denied` before the call." },
14
+ "modelDeny": { "type": "array", "items": { "type": "string" }, "uniqueItems": true, "description": "Optional denylist. `modelDeny` wins on conflict with `modelAllow` (fail-closed)." },
15
+ "thresholdPercent": { "type": "number", "minimum": 0, "maximum": 100, "description": "Emit `budget.threshold.crossed` once per dimension at this percent of the dimension's limit." },
16
+ "onExhaustion": { "type": "string", "enum": ["fail", "interrupt"], "description": "`fail` (default): `cap.breached{kind:\"budget-*\"}` → `run.failed{budget_exhausted}`. `interrupt`: raise an RFC 0051 approval interrupt so a human MAY extend the budget." }
17
+ }
18
+ }