@openwop/spec-artifacts 2.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CORPUS-STAMP.json +234 -0
- package/LICENSE +201 -0
- package/README.md +7 -0
- package/api/.redocly.lint-ignore.yaml +22 -0
- package/api/asyncapi.yaml +834 -0
- package/api/grpc/openwop.proto +251 -0
- package/api/openapi.yaml +2693 -0
- package/api/redocly.yaml +23 -0
- package/api/seams-v2.yaml +680 -0
- package/api/v2/asyncapi.yaml +528 -0
- package/api/v2/openapi.yaml +3139 -0
- package/api/v2/redocly.yaml +16 -0
- package/package.json +10 -0
- package/schemas/README.md +144 -0
- package/schemas/a2a-task-state.schema.json +78 -0
- package/schemas/a2ui-surface-delta-frame.schema.json +48 -0
- package/schemas/agent-deployment-transition.schema.json +49 -0
- package/schemas/agent-deployment.schema.json +54 -0
- package/schemas/agent-eval-suite.schema.json +140 -0
- package/schemas/agent-inventory-response.schema.json +115 -0
- package/schemas/agent-manifest.schema.json +156 -0
- package/schemas/agent-org-chart.schema.json +82 -0
- package/schemas/agent-ref.schema.json +63 -0
- package/schemas/agent-roster-entry.schema.json +81 -0
- package/schemas/agent-roster-response.schema.json +21 -0
- package/schemas/ai-envelope.schema.json +134 -0
- package/schemas/annotation-create.schema.json +37 -0
- package/schemas/annotation.schema.json +56 -0
- package/schemas/artifact-type-pack-manifest.schema.json +244 -0
- package/schemas/audit-verify-result.schema.json +90 -0
- package/schemas/budget-policy.schema.json +18 -0
- package/schemas/capabilities.schema.json +4160 -0
- package/schemas/certification-bundle-v2.schema.json +118 -0
- package/schemas/channel-presence-payload.schema.json +41 -0
- package/schemas/channel-written-payload.schema.json +55 -0
- package/schemas/chat-card-pack-manifest.schema.json +253 -0
- package/schemas/compact-tool-descriptor.schema.json +51 -0
- package/schemas/compensation-policy.schema.json +64 -0
- package/schemas/conformance-certification-bundle.schema.json +86 -0
- package/schemas/connection-pack-manifest.schema.json +353 -0
- package/schemas/conversation-event.schema.json +168 -0
- package/schemas/conversation-turn.schema.json +117 -0
- package/schemas/core-conformance-mock-agent-config.schema.json +152 -0
- package/schemas/credential-provenance.schema.json +18 -0
- package/schemas/credential-reference.schema.json +21 -0
- package/schemas/debug-bundle.schema.json +196 -0
- package/schemas/dispatch-config.schema.json +112 -0
- package/schemas/envelopes/clarification.request.schema.json +52 -0
- package/schemas/envelopes/error.schema.json +30 -0
- package/schemas/envelopes/media.audio.schema.json +38 -0
- package/schemas/envelopes/media.file.schema.json +37 -0
- package/schemas/envelopes/media.image.schema.json +33 -0
- package/schemas/envelopes/schema.request.schema.json +26 -0
- package/schemas/envelopes/schema.response.schema.json +22 -0
- package/schemas/envelopes/ui.a2ui-surface.schema.json +154 -0
- package/schemas/error-envelope.schema.json +25 -0
- package/schemas/eval-summary.schema.json +92 -0
- package/schemas/export-bundle.schema.json +66 -0
- package/schemas/form-content-pack-manifest.schema.json +243 -0
- package/schemas/frontend-plugin-manifest.schema.json +109 -0
- package/schemas/goal.schema.json +104 -0
- package/schemas/heartbeat-evaluated.schema.json +14 -0
- package/schemas/heartbeat-state-changed.schema.json +14 -0
- package/schemas/localized-content-language-settings.schema.json +26 -0
- package/schemas/localized-content-page-response.schema.json +60 -0
- package/schemas/localized-content-page.schema.json +62 -0
- package/schemas/localized-content-section.schema.json +51 -0
- package/schemas/memory-entry.schema.json +36 -0
- package/schemas/memory-list-options.schema.json +37 -0
- package/schemas/node-pack-manifest.schema.json +654 -0
- package/schemas/orchestrator-decision.schema.json +90 -0
- package/schemas/org-chart-responsibility-view.schema.json +26 -0
- package/schemas/pack-lockfile.schema.json +108 -0
- package/schemas/prompt-kind.schema.json +8 -0
- package/schemas/prompt-pack-manifest.schema.json +117 -0
- package/schemas/prompt-ref.schema.json +40 -0
- package/schemas/prompt-template.schema.json +149 -0
- package/schemas/proposal.schema.json +84 -0
- package/schemas/registry-version-manifest.schema.json +208 -0
- package/schemas/residency.schema.json +16 -0
- package/schemas/run-ancestry-response.schema.json +54 -0
- package/schemas/run-diff-response.schema.json +64 -0
- package/schemas/run-event-payloads.schema.json +4452 -0
- package/schemas/run-event.schema.json +211 -0
- package/schemas/run-options.schema.json +80 -0
- package/schemas/run-orchestrator-decided-event.schema.json +20 -0
- package/schemas/run-snapshot.schema.json +148 -0
- package/schemas/security-advisory.schema.json +109 -0
- package/schemas/self-hosted-runner-dispatch-frame.schema.json +79 -0
- package/schemas/self-hosted-runner-registration.schema.json +53 -0
- package/schemas/self-hosted-runner-result-frame.schema.json +38 -0
- package/schemas/subject.schema.json +56 -0
- package/schemas/suspend-request.schema.json +207 -0
- package/schemas/tool-descriptor.schema.json +63 -0
- package/schemas/trigger-event.schema.json +222 -0
- package/schemas/trigger-subscription-registration.schema.json +67 -0
- package/schemas/trigger-subscription.schema.json +26 -0
- package/schemas/ui-plugin-message.schema.json +90 -0
- package/schemas/v2/a2a-task-state.schema.json +102 -0
- package/schemas/v2/a2ui-surface-delta-frame.schema.json +62 -0
- package/schemas/v2/agent-deployment-transition.schema.json +67 -0
- package/schemas/v2/agent-deployment.schema.json +68 -0
- package/schemas/v2/agent-eval-suite.schema.json +214 -0
- package/schemas/v2/agent-inventory-response.schema.json +172 -0
- package/schemas/v2/agent-manifest.schema.json +218 -0
- package/schemas/v2/agent-org-chart.schema.json +149 -0
- package/schemas/v2/agent-ref.schema.json +67 -0
- package/schemas/v2/agent-roster-entry.schema.json +104 -0
- package/schemas/v2/agent-roster-response.schema.json +27 -0
- package/schemas/v2/ai-envelope.schema.json +167 -0
- package/schemas/v2/annotation-create.schema.json +109 -0
- package/schemas/v2/annotation.schema.json +142 -0
- package/schemas/v2/artifact-type-pack-manifest.schema.json +245 -0
- package/schemas/v2/audit-verify-result.schema.json +110 -0
- package/schemas/v2/budget-policy.schema.json +61 -0
- package/schemas/v2/capabilities.schema.json +7644 -0
- package/schemas/v2/certification-bundle.schema.json +401 -0
- package/schemas/v2/channel-presence-payload.schema.json +60 -0
- package/schemas/v2/channel-written-payload.schema.json +64 -0
- package/schemas/v2/chat-card-pack-manifest.schema.json +254 -0
- package/schemas/v2/compact-tool-descriptor.schema.json +108 -0
- package/schemas/v2/compensation-policy.schema.json +91 -0
- package/schemas/v2/compensation-projection.schema.json +95 -0
- package/schemas/v2/configurable.schema.json +110 -0
- package/schemas/v2/connection-pack-manifest.schema.json +354 -0
- package/schemas/v2/conversation-event.schema.json +281 -0
- package/schemas/v2/conversation-turn.schema.json +165 -0
- package/schemas/v2/credential-provenance.schema.json +62 -0
- package/schemas/v2/credential-reference.schema.json +28 -0
- package/schemas/v2/debug-bundle.schema.json +312 -0
- package/schemas/v2/dispatch-config.schema.json +147 -0
- package/schemas/v2/effect-ledger-projection.schema.json +71 -0
- package/schemas/v2/effect-seam-manifest.schema.json +98 -0
- package/schemas/v2/envelopes/clarification.request.schema.json +59 -0
- package/schemas/v2/envelopes/error.schema.json +35 -0
- package/schemas/v2/envelopes/media.audio.schema.json +41 -0
- package/schemas/v2/envelopes/media.file.schema.json +40 -0
- package/schemas/v2/envelopes/media.image.schema.json +36 -0
- package/schemas/v2/envelopes/schema.request.schema.json +29 -0
- package/schemas/v2/envelopes/schema.response.schema.json +26 -0
- package/schemas/v2/envelopes/ui.a2ui-surface.schema.json +292 -0
- package/schemas/v2/error-envelope.schema.json +229 -0
- package/schemas/v2/eval-summary.schema.json +166 -0
- package/schemas/v2/export-bundle.schema.json +94 -0
- package/schemas/v2/form-content-pack-manifest.schema.json +241 -0
- package/schemas/v2/frontend-plugin-manifest.schema.json +152 -0
- package/schemas/v2/goal.schema.json +188 -0
- package/schemas/v2/heartbeat-evaluated.schema.json +34 -0
- package/schemas/v2/heartbeat-state-changed.schema.json +31 -0
- package/schemas/v2/ids.schema.json +31 -0
- package/schemas/v2/localized-content-language-settings.schema.json +34 -0
- package/schemas/v2/localized-content-page-response.schema.json +94 -0
- package/schemas/v2/localized-content-page.schema.json +87 -0
- package/schemas/v2/localized-content-section.schema.json +63 -0
- package/schemas/v2/memory-entry.schema.json +45 -0
- package/schemas/v2/memory-list-options.schema.json +41 -0
- package/schemas/v2/node-pack-manifest.schema.json +657 -0
- package/schemas/v2/orchestrator-decision.schema.json +120 -0
- package/schemas/v2/org-chart-responsibility-view.schema.json +36 -0
- package/schemas/v2/pack-lockfile.schema.json +139 -0
- package/schemas/v2/prompt-kind.schema.json +14 -0
- package/schemas/v2/prompt-pack-manifest.schema.json +118 -0
- package/schemas/v2/prompt-ref.schema.json +42 -0
- package/schemas/v2/prompt-template.schema.json +209 -0
- package/schemas/v2/proposal.schema.json +145 -0
- package/schemas/v2/registry-version-manifest.schema.json +292 -0
- package/schemas/v2/residency.schema.json +19 -0
- package/schemas/v2/run-ancestry-response.schema.json +68 -0
- package/schemas/v2/run-diff-response.schema.json +80 -0
- package/schemas/v2/run-event-payloads.schema.json +4588 -0
- package/schemas/v2/run-event.schema.json +324 -0
- package/schemas/v2/run-options.schema.json +90 -0
- package/schemas/v2/run-orchestrator-decided-event.schema.json +22 -0
- package/schemas/v2/run-snapshot.schema.json +207 -0
- package/schemas/v2/security-advisory.schema.json +138 -0
- package/schemas/v2/self-hosted-runner-dispatch-frame.schema.json +119 -0
- package/schemas/v2/self-hosted-runner-registration.schema.json +74 -0
- package/schemas/v2/self-hosted-runner-result-frame.schema.json +47 -0
- package/schemas/v2/subject-link.schema.json +69 -0
- package/schemas/v2/subject.schema.json +597 -0
- package/schemas/v2/suspend-request.schema.json +370 -0
- package/schemas/v2/tool-descriptor.schema.json +150 -0
- package/schemas/v2/trigger-event.schema.json +508 -0
- package/schemas/v2/trigger-subscription-registration.schema.json +99 -0
- package/schemas/v2/trigger-subscription.schema.json +79 -0
- package/schemas/v2/ui-plugin-message.schema.json +149 -0
- package/schemas/v2/workflow-chain-pack-manifest.schema.json +610 -0
- package/schemas/v2/workflow-definition.schema.json +864 -0
- package/schemas/v2/workload-identity.schema.json +115 -0
- package/schemas/v2/workspace-file-create.schema.json +23 -0
- package/schemas/v2/workspace-file.schema.json +45 -0
- package/schemas/workflow-chain-pack-manifest.schema.json +615 -0
- package/schemas/workflow-definition.schema.json +850 -0
- package/schemas/workload-identity.schema.json +79 -0
- package/schemas/workspace-file-create.schema.json +20 -0
- package/schemas/workspace-file.schema.json +39 -0
- package/spec/v1/alias-detectors.json +283 -0
- package/spec/v1/capability-declaration-classes.json +176 -0
- package/spec/v1/core-standard-manifest.json +423 -0
- package/spec/v1/deprecations.json +854 -0
- package/spec/v1/deprecations.schema.json +187 -0
- package/spec/v1/event-codemap.json +1089 -0
- package/spec/v1/event-codemap.schema.json +41 -0
- package/spec/v1/extensions.json +1273 -0
- package/spec/v1/gaps.json +14581 -0
- package/spec/v1/gaps.schema.json +55 -0
- package/spec/v1/migrations.json +1822 -0
- package/spec/v1/migrations.schema.json +44 -0
- package/spec/v1/operation-path-manifest.json +462 -0
- package/spec/v1/spec-gaps.json +4823 -0
- package/spec/v2/declaration.json +1862 -0
- package/spec/v2/declaration.schema.json +305 -0
- package/spec/v2/errors.json +837 -0
- package/spec/v2/event-codemap.json +1099 -0
- package/spec/v2/event-codemap.schema.json +114 -0
- package/spec/v2/ext/provider-idempotency/registry.json +6 -0
- package/spec/v2/facets/a2a.schema.json +51 -0
- package/spec/v2/facets/aiProviders.schema.json +56 -0
- package/spec/v2/facets/auth.schema.json +91 -0
- package/spec/v2/facets/heartbeat.schema.json +20 -0
- package/spec/v2/facets/interrupt.schema.json +29 -0
- package/spec/v2/facets/mcp.schema.json +81 -0
- package/spec/v2/facets/replay.schema.json +34 -0
- package/spec/v2/facets/sandbox.schema.json +31 -0
- package/spec/v2/facets/webhooks.schema.json +18 -0
- package/spec/v2/path-manifest.json +279 -0
- package/spec/v2/peer-dependency-aliases.json +165 -0
- package/spec/v2/profiles.json +45 -0
- package/spec/v2/release.json +6 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://openwop.dev/spec/v2/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": [
|
|
9
|
+
"bundleVersion",
|
|
10
|
+
"source",
|
|
11
|
+
"items"
|
|
12
|
+
],
|
|
13
|
+
"properties": {
|
|
14
|
+
"bundleVersion": {
|
|
15
|
+
"const": "2",
|
|
16
|
+
"description": "RFC 0172 §B axis 10 — one const family; this bundle is \"2\" in v2."
|
|
17
|
+
},
|
|
18
|
+
"source": {
|
|
19
|
+
"type": "object",
|
|
20
|
+
"additionalProperties": false,
|
|
21
|
+
"required": [
|
|
22
|
+
"origin"
|
|
23
|
+
],
|
|
24
|
+
"description": "Provenance of the bundle. Informational only — never a source of authority at the destination.",
|
|
25
|
+
"properties": {
|
|
26
|
+
"origin": {
|
|
27
|
+
"type": "string",
|
|
28
|
+
"minLength": 1,
|
|
29
|
+
"description": "Origin host base URL or adapter id (e.g. 'adapter:openclaw')."
|
|
30
|
+
},
|
|
31
|
+
"exportedAt": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"format": "date-time"
|
|
34
|
+
},
|
|
35
|
+
"originPrincipal": {
|
|
36
|
+
"type": [
|
|
37
|
+
"string",
|
|
38
|
+
"null"
|
|
39
|
+
],
|
|
40
|
+
"default": null,
|
|
41
|
+
"description": "Opaque source identity, informational only. MUST NOT grant any access at the destination."
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"items": {
|
|
46
|
+
"type": "array",
|
|
47
|
+
"description": "The estate, in arbitrary order; `dependsOn` edges define apply order (topological; a cycle is a 422).",
|
|
48
|
+
"items": {
|
|
49
|
+
"type": "object",
|
|
50
|
+
"additionalProperties": false,
|
|
51
|
+
"required": [
|
|
52
|
+
"kind",
|
|
53
|
+
"ref",
|
|
54
|
+
"payload"
|
|
55
|
+
],
|
|
56
|
+
"properties": {
|
|
57
|
+
"kind": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"enum": [
|
|
60
|
+
"agent",
|
|
61
|
+
"pack",
|
|
62
|
+
"prompt-template",
|
|
63
|
+
"connection-ref",
|
|
64
|
+
"schedule",
|
|
65
|
+
"roster",
|
|
66
|
+
"org-chart"
|
|
67
|
+
],
|
|
68
|
+
"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)."
|
|
69
|
+
},
|
|
70
|
+
"ref": {
|
|
71
|
+
"type": "string",
|
|
72
|
+
"minLength": 1,
|
|
73
|
+
"description": "Stable id within the bundle, used as the target of `dependsOn` edges."
|
|
74
|
+
},
|
|
75
|
+
"dependsOn": {
|
|
76
|
+
"type": "array",
|
|
77
|
+
"items": {
|
|
78
|
+
"type": "string"
|
|
79
|
+
},
|
|
80
|
+
"default": [],
|
|
81
|
+
"description": "Refs of other items that MUST be applied before this one (topological order)."
|
|
82
|
+
},
|
|
83
|
+
"payload": {
|
|
84
|
+
"type": "object",
|
|
85
|
+
"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).",
|
|
86
|
+
"$comment": "Intentionally open object — validated against the kind's own schema; connection-ref payloads MUST NOT contain credential values (export-bundle-no-credential-material).",
|
|
87
|
+
"additionalProperties": true
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"x-openwop-seeded-from": "v1"
|
|
94
|
+
}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://openwop.dev/spec/v2/form-content-pack-manifest.schema.json",
|
|
4
|
+
"title": "FormContentPackManifest",
|
|
5
|
+
"description": "Manifest for a published OpenWOP form-content pack — `pack.json` at the pack root with `kind: \"form-content\"`. Peer to the node / workflow-chain / prompt / artifact-type / card pack manifests; disjoint via the `kind` discriminator. See `spec/v1/form-content-packs.md` for the canonical contract and RFC 0137 for the rationale.\n\nA form-content pack distributes **form templates**: a named, versioned set of typed input fields a host instantiates into an ordinary, fully editable form through its normal create path. It is purely declarative — no `runtime`, no executor bytecode, no entry point. The pack contributes the *shape* of a form; it does not define a submission surface, a handler, or any behavior the host would not otherwise accept.\n\n**A template carries NO submission routing, and MUST NOT gain any.** There is deliberately no `intakeBinding` / destination / webhook / list-id property on `FormTemplate`, and `additionalProperties: false` rejects one. Where a tenant's form submissions go is a decision about the OPERATOR's data; a third-party pack author does not get to make it by shipping a manifest. Enforced as the `form-content-template-no-submission-routing` SECURITY invariant — see `form-content-packs.md` §\"No submission routing\".\n\n**The wire vocabulary governs the WIRE, not host storage.** A host MAY store fields under any internal representation it likes and translate at the pack boundary; the spec constrains what crosses the wire, not what sits in a host's database (`positioning.md`).\n\n**Field types are the RFC 0071 portable subset, not a second vocabulary.** `fields[].type` reuses the closed portable subset defined in `chat-card-packs.md` §\"Input fields — a closed portable subset\" (RFC 0071 Phase 2, gap G9 resolved 2026-05-27) verbatim, including its `vendor.<org>.<kind>` / `x-<kind>` extension escape hatch. Two declarative pack kinds that both collect typed user input MUST agree on what a field type means.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"name",
|
|
9
|
+
"version",
|
|
10
|
+
"kind",
|
|
11
|
+
"engines",
|
|
12
|
+
"templates"
|
|
13
|
+
],
|
|
14
|
+
"additionalProperties": false,
|
|
15
|
+
"properties": {
|
|
16
|
+
"kind": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"const": "form-content",
|
|
19
|
+
"description": "Pack kind discriminator. MUST be the literal string `\"form-content\"`."
|
|
20
|
+
},
|
|
21
|
+
"name": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"description": "Reverse-DNS pack name per `node-packs.md` §Naming. Reserved scopes are identical (`core.*` / `vendor.<org>.*` / `community.<author>.*` / `private.<host>.*`).",
|
|
24
|
+
"pattern": "^(core|vendor|community|private)\\.[a-z][a-z0-9_-]*(\\.[a-z][a-zA-Z0-9_-]*)+$",
|
|
25
|
+
"minLength": 1,
|
|
26
|
+
"maxLength": 256
|
|
27
|
+
},
|
|
28
|
+
"version": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"description": "Pack-level SemVer 2.0.0.",
|
|
31
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$"
|
|
32
|
+
},
|
|
33
|
+
"description": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"maxLength": 1024
|
|
36
|
+
},
|
|
37
|
+
"author": {
|
|
38
|
+
"type": "string"
|
|
39
|
+
},
|
|
40
|
+
"license": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"description": "SPDX license identifier (e.g., `Apache-2.0`, `MIT`)."
|
|
43
|
+
},
|
|
44
|
+
"homepage": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"format": "uri"
|
|
47
|
+
},
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "string",
|
|
50
|
+
"format": "uri"
|
|
51
|
+
},
|
|
52
|
+
"keywords": {
|
|
53
|
+
"type": "array",
|
|
54
|
+
"items": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"maxLength": 64
|
|
57
|
+
},
|
|
58
|
+
"maxItems": 50
|
|
59
|
+
},
|
|
60
|
+
"engines": {
|
|
61
|
+
"type": "object",
|
|
62
|
+
"required": [
|
|
63
|
+
"openwop"
|
|
64
|
+
],
|
|
65
|
+
"properties": {
|
|
66
|
+
"openwop": {
|
|
67
|
+
"type": "string",
|
|
68
|
+
"description": "Semver range — which openwop protocol versions this pack works against."
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
"additionalProperties": false
|
|
72
|
+
},
|
|
73
|
+
"dependencies": {
|
|
74
|
+
"type": "object",
|
|
75
|
+
"additionalProperties": {
|
|
76
|
+
"type": "string"
|
|
77
|
+
},
|
|
78
|
+
"description": "Other packs this pack depends on. Map of pack name → semver range."
|
|
79
|
+
},
|
|
80
|
+
"peerDependencies": {
|
|
81
|
+
"type": "object",
|
|
82
|
+
"additionalProperties": {
|
|
83
|
+
"type": "string"
|
|
84
|
+
},
|
|
85
|
+
"description": "Engine-supplied capabilities the pack consumes (e.g., `{ \"host.forms.contentPacks\": \"supported\" }`). Resolved against the host's advertised capabilities at register time."
|
|
86
|
+
},
|
|
87
|
+
"templates": {
|
|
88
|
+
"type": "array",
|
|
89
|
+
"minItems": 1,
|
|
90
|
+
"maxItems": 100,
|
|
91
|
+
"items": {
|
|
92
|
+
"$ref": "#/$defs/FormTemplate"
|
|
93
|
+
},
|
|
94
|
+
"description": "Form template definitions this pack contributes. Each MUST have a unique `templateId` within the pack — duplicates MUST be refused at registry `PUT` / install (`form-content-packs.md` §\"Unique identifiers\"); JSON Schema cannot express uniqueness-by-property, so this is a normative prose requirement, as it is for every peer pack kind. `maxItems` is an OUTER resource bound against a render bomb, not product policy — a host MAY enforce a tighter limit locally."
|
|
95
|
+
},
|
|
96
|
+
"signing": {
|
|
97
|
+
"$ref": "#/$defs/Signing"
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"$defs": {
|
|
101
|
+
"FormTemplate": {
|
|
102
|
+
"type": "object",
|
|
103
|
+
"required": [
|
|
104
|
+
"templateId",
|
|
105
|
+
"version",
|
|
106
|
+
"label",
|
|
107
|
+
"title",
|
|
108
|
+
"fields"
|
|
109
|
+
],
|
|
110
|
+
"additionalProperties": false,
|
|
111
|
+
"properties": {
|
|
112
|
+
"templateId": {
|
|
113
|
+
"$ref": "ids.schema.json#/$defs/templateId",
|
|
114
|
+
"description": "Reverse-DNS template identifier. Same pattern and reserved scopes as a pack `name`. This is the id a registry denormalizes for discovery (`registry-operations.md` §\"Type-ID indexing\") and the id a host resolves when instantiating. Third parties MUST NOT publish under `core.*`."
|
|
115
|
+
},
|
|
116
|
+
"version": {
|
|
117
|
+
"type": "string",
|
|
118
|
+
"description": "Per-template SemVer 2.0.0 — the SAME axis as the pack `version`, NOT the non-negative-integer schema-version axis used by `chat-card-pack-manifest.schema.json` `schemaVersion` / `artifact-type-pack-manifest.schema.json` `schemaVersion`. A form template is a distributable artifact whose shape changes are author-meaningful (a removed field is a breaking change to anything storing its submissions), so it carries the same SemVer contract as the pack.",
|
|
119
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$"
|
|
120
|
+
},
|
|
121
|
+
"label": {
|
|
122
|
+
"type": "string",
|
|
123
|
+
"minLength": 1,
|
|
124
|
+
"maxLength": 200,
|
|
125
|
+
"description": "Short human-readable name for a picker / gallery listing. UNTRUSTED pack-authored content — see `form-content-packs.md` §\"Trust boundary\". The length bound is a resource guard, NOT a trust boundary."
|
|
126
|
+
},
|
|
127
|
+
"title": {
|
|
128
|
+
"type": "string",
|
|
129
|
+
"minLength": 1,
|
|
130
|
+
"maxLength": 200,
|
|
131
|
+
"description": "Heading rendered above the instantiated form. UNTRUSTED pack-authored content — see `form-content-packs.md` §\"Trust boundary\"."
|
|
132
|
+
},
|
|
133
|
+
"description": {
|
|
134
|
+
"type": "string",
|
|
135
|
+
"maxLength": 300,
|
|
136
|
+
"description": "Optional explanatory copy. UNTRUSTED pack-authored content — see `form-content-packs.md` §\"Trust boundary\"."
|
|
137
|
+
},
|
|
138
|
+
"category": {
|
|
139
|
+
"type": "string",
|
|
140
|
+
"maxLength": 64,
|
|
141
|
+
"description": "Optional grouping hint for a picker. Advisory — the spec assigns no meaning to any particular value and a host MUST NOT treat it as an authorization or visibility boundary."
|
|
142
|
+
},
|
|
143
|
+
"fields": {
|
|
144
|
+
"type": "array",
|
|
145
|
+
"minItems": 1,
|
|
146
|
+
"maxItems": 200,
|
|
147
|
+
"items": {
|
|
148
|
+
"$ref": "#/$defs/FormField"
|
|
149
|
+
},
|
|
150
|
+
"description": "Typed fields the template contributes, in presentation order. Each MUST have a unique `id` within the template — duplicates MUST be refused (`form-content-packs.md` §\"Unique identifiers\"). Two fields sharing an `id` silently overwrite one another in the submission value bag, losing data with no error, so this is a data-integrity requirement rather than a style rule. `maxItems` is an OUTER resource bound; a host MAY enforce a tighter limit locally."
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
"patternProperties": {
|
|
154
|
+
"^(openwop-|x-|vendor\\.)": {
|
|
155
|
+
"description": "Vendor / host extension escape hatch (RFC 0138). A property matching `^(x-|vendor\\.)` is a HOST EXTENSION: its semantics are unspecified by this protocol, and a consumer that does not recognize one MUST ignore it rather than reject the pack. Resolves the contradiction in `host-extensions.md` §\"Vendor-prefixed namespaces\", which requires a client receiving an unknown vendor-prefixed field to treat it as opaque — a field that `additionalProperties: false` previously made impossible to carry. SECURITY: an extension value is PACK-AUTHORED, therefore untrusted; \"ignore\" means ignore. See `node-packs.md` §\"Vendor extensions on pack manifests\" and the `pack-manifest-extension-opaque` invariant."
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
"FormField": {
|
|
160
|
+
"type": "object",
|
|
161
|
+
"required": [
|
|
162
|
+
"id",
|
|
163
|
+
"type",
|
|
164
|
+
"label"
|
|
165
|
+
],
|
|
166
|
+
"additionalProperties": false,
|
|
167
|
+
"description": "One typed field. `id` (not `key`) matches `chat-card-pack-manifest.schema.json#/$defs/InputField` so a host renders both declarative kinds through the same machinery.",
|
|
168
|
+
"properties": {
|
|
169
|
+
"id": {
|
|
170
|
+
"type": "string",
|
|
171
|
+
"minLength": 1,
|
|
172
|
+
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$",
|
|
173
|
+
"description": "Field identifier, unique within the template. Mirrors `chat-card-pack-manifest.schema.json` `InputField.id`."
|
|
174
|
+
},
|
|
175
|
+
"type": {
|
|
176
|
+
"type": "string",
|
|
177
|
+
"description": "Closed portable subset OR a `vendor.<org>.<kind>` / `x-<kind>` host extension other hosts MUST ignore (degrading to a plain text input). The subset is IDENTICAL to `chat-card-pack-manifest.schema.json` `InputField.type` (RFC 0071 G9, resolved 2026-05-27): `text`, `longtext`, `number`, `boolean`, `select`, `multiselect`, `file`, `artifact-ref`. Named by DATA KIND, not widget — a host renders `boolean` as whatever toggle/checkbox it likes, and `longtext` as whatever multi-line control it likes. Validation formats (`email`, `uri`, …) are NOT types; use `format`.",
|
|
178
|
+
"pattern": "^(text|longtext|number|boolean|select|multiselect|file|artifact-ref|vendor\\.[a-z][a-z0-9-]*\\.[a-z][a-z0-9-]*|x-[a-z][a-z0-9-]*)$"
|
|
179
|
+
},
|
|
180
|
+
"format": {
|
|
181
|
+
"type": "string",
|
|
182
|
+
"description": "Optional validation-format constraint on the field's value, following the JSON Schema `format` idiom used throughout this corpus. Spec-reserved core identifiers: `email`, `uri`, `date`, `date-time`, `time`. Host extensions MUST be `x-<format>`-prefixed. Only meaningful for `type: \"text\"` / `\"longtext\"`; a host MUST ignore it on any other type. A host that recognizes the format SHOULD apply it as an input-validation constraint; a host that does NOT recognize it MUST ignore it and accept the value as plain text (the same degradation contract as an unrecognized `type`). `format` is a CONSTRAINT on a `text` field — it is deliberately not a member of the `type` vocabulary, so the portable type set stays a stable set of data kinds instead of accreting widgets.",
|
|
183
|
+
"pattern": "^(email|uri|date|date-time|time|x-[a-z][a-z0-9-]*)$"
|
|
184
|
+
},
|
|
185
|
+
"label": {
|
|
186
|
+
"type": "string",
|
|
187
|
+
"minLength": 1,
|
|
188
|
+
"maxLength": 1000,
|
|
189
|
+
"description": "Human-readable field label. Bounded at 1000 rather than 200 because a lawful consent label (GDPR/marketing opt-in) is legitimately long-form. UNTRUSTED pack-authored content — see `form-content-packs.md` §\"Trust boundary\"."
|
|
190
|
+
},
|
|
191
|
+
"description": {
|
|
192
|
+
"type": "string",
|
|
193
|
+
"maxLength": 300,
|
|
194
|
+
"description": "Optional help text. UNTRUSTED pack-authored content — see `form-content-packs.md` §\"Trust boundary\"."
|
|
195
|
+
},
|
|
196
|
+
"required": {
|
|
197
|
+
"type": "boolean",
|
|
198
|
+
"description": "Whether the host SHOULD require a value before accepting the instantiated form. Absent ⇒ `false`."
|
|
199
|
+
},
|
|
200
|
+
"default": {
|
|
201
|
+
"description": "Optional default value. Its JSON type SHOULD match the field `type` (string for `text`/`longtext`, number for `number`, boolean for `boolean`, string for `select`, array of string for `multiselect`); a host MUST ignore a default whose type does not match rather than fail the instantiation."
|
|
202
|
+
},
|
|
203
|
+
"options": {
|
|
204
|
+
"type": "array",
|
|
205
|
+
"items": {
|
|
206
|
+
"type": "string",
|
|
207
|
+
"maxLength": 200
|
|
208
|
+
},
|
|
209
|
+
"maxItems": 250,
|
|
210
|
+
"description": "Choices for `type: \"select\"` / `\"multiselect\"`. UNTRUSTED pack-authored content — see `form-content-packs.md` §\"Trust boundary\". Mirrors `chat-card-pack-manifest.schema.json` `InputField.options`."
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
"Signing": {
|
|
215
|
+
"type": "object",
|
|
216
|
+
"description": "Optional signing metadata. See node-packs.md §signing.",
|
|
217
|
+
"additionalProperties": false,
|
|
218
|
+
"properties": {
|
|
219
|
+
"publicKeyRef": {
|
|
220
|
+
"type": "string"
|
|
221
|
+
},
|
|
222
|
+
"signatureRef": {
|
|
223
|
+
"type": "string"
|
|
224
|
+
},
|
|
225
|
+
"method": {
|
|
226
|
+
"type": "string",
|
|
227
|
+
"enum": [
|
|
228
|
+
"manual",
|
|
229
|
+
"sigstore"
|
|
230
|
+
]
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
"patternProperties": {
|
|
236
|
+
"^(openwop-|x-|vendor\\.)": {
|
|
237
|
+
"description": "Vendor / host extension escape hatch (RFC 0138). A property matching `^(x-|vendor\\.)` is a HOST EXTENSION: its semantics are unspecified by this protocol, and a consumer that does not recognize one MUST ignore it rather than reject the pack. Resolves the contradiction in `host-extensions.md` §\"Vendor-prefixed namespaces\", which requires a client receiving an unknown vendor-prefixed field to treat it as opaque — a field that `additionalProperties: false` previously made impossible to carry. SECURITY: an extension value is PACK-AUTHORED, therefore untrusted; \"ignore\" means ignore. See `node-packs.md` §\"Vendor extensions on pack manifests\" and the `pack-manifest-extension-opaque` invariant."
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
"x-openwop-seeded-from": "v1"
|
|
241
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://openwop.dev/spec/v2/frontend-plugin-manifest.schema.json",
|
|
4
|
+
"title": "FrontendPluginManifest",
|
|
5
|
+
"description": "RFC 0117. Manifest for a published OpenWOP front-end plugin pack — `pack.json` at the pack root with `kind: \"frontend-plugin\"`. Peer to and disjoint from `node-pack-manifest.schema.json` (RFC 0003), `connection-pack-manifest.schema.json` (RFC 0095), and the other pack kinds via the `kind` discriminator. A front-end plugin pack distributes a SIGNED, SANDBOXED user-interface extension (a canvas editor, a custom artifact viewer, a settings panel) that a host loads at runtime in an ORIGIN/EXECUTION-ISOLATED sandbox (a cross-origin iframe by default, or an equivalent WASM/process/container/VM sandbox per `capabilities.uiPlugins.isolation`, RFC 0119) and enables through its own admin surface. The wire owns only the manifest shape, the isolation model, and the `ui-plugin/1` host-RPC boundary — NOT a rendering runtime: the plugin `entry` bundle is opaque bytes the host runs in a sandbox. Carries NO secret and NO backend `runtime` (a `runtime` member is rejected — a plugin is sandboxed UI, not a node entry). Requires the host to advertise `capabilities.uiPlugins.supported: true`; degrades to nothing on hosts without it. See `spec/v1/frontend-plugin-packs.md`.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"name",
|
|
9
|
+
"version",
|
|
10
|
+
"kind",
|
|
11
|
+
"engines",
|
|
12
|
+
"uiPlugins"
|
|
13
|
+
],
|
|
14
|
+
"additionalProperties": false,
|
|
15
|
+
"properties": {
|
|
16
|
+
"name": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"description": "Reverse-DNS pack name per `node-packs.md` §Naming. Reserved scopes are identical (`core.*` / `vendor.<org>.*` / `community.<author>.*` / `private.<host>.*`). Mirror of `connection-pack-manifest.schema.json#/properties/name`.",
|
|
19
|
+
"pattern": "^(core|vendor|community|private)\\.[a-z][a-z0-9_-]*(\\.[a-z][a-zA-Z0-9_-]*)+$",
|
|
20
|
+
"minLength": 1,
|
|
21
|
+
"maxLength": 256
|
|
22
|
+
},
|
|
23
|
+
"version": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"description": "Pack-level SemVer 2.0.0.",
|
|
26
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$"
|
|
27
|
+
},
|
|
28
|
+
"kind": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"const": "frontend-plugin",
|
|
31
|
+
"description": "Pack kind discriminator. MUST be the literal string `\"frontend-plugin\"` for this schema."
|
|
32
|
+
},
|
|
33
|
+
"description": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"maxLength": 1024
|
|
36
|
+
},
|
|
37
|
+
"author": {
|
|
38
|
+
"type": "string"
|
|
39
|
+
},
|
|
40
|
+
"license": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"description": "SPDX license identifier (e.g., `Apache-2.0`)."
|
|
43
|
+
},
|
|
44
|
+
"homepage": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"format": "uri"
|
|
47
|
+
},
|
|
48
|
+
"engines": {
|
|
49
|
+
"type": "object",
|
|
50
|
+
"description": "Compatibility floor. `openwop` is the spec range the pack targets; mirror of the other pack manifests.",
|
|
51
|
+
"required": [
|
|
52
|
+
"openwop"
|
|
53
|
+
],
|
|
54
|
+
"additionalProperties": false,
|
|
55
|
+
"properties": {
|
|
56
|
+
"openwop": {
|
|
57
|
+
"type": "string",
|
|
58
|
+
"description": "SemVer range of the OpenWOP spec this pack targets (e.g., `>=1.2.0`)."
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"runtime": {
|
|
63
|
+
"not": {},
|
|
64
|
+
"description": "FORBIDDEN. A front-end plugin is sandboxed UI, not a backend node `runtime`. A manifest that carries `runtime` under `kind: \"frontend-plugin\"` MUST be rejected at registration with `pack_kind_invalid` (RFC 0117 §Negative). Declared here as `not: {}` so any value fails validation."
|
|
65
|
+
},
|
|
66
|
+
"uiPlugins": {
|
|
67
|
+
"type": "array",
|
|
68
|
+
"description": "The plugin surfaces this pack supplies. A pack MUST declare at least one. A host installs the pack but renders only those whose `surface` is in `capabilities.uiPlugins.surfaces` and whose `hostApi` methods are a subset of `capabilities.uiPlugins.hostApi` — the rest are installable-but-inert (§Degradation), never an error.",
|
|
69
|
+
"minItems": 1,
|
|
70
|
+
"items": {
|
|
71
|
+
"$ref": "#/$defs/uiPlugin"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"patternProperties": {
|
|
76
|
+
"^(openwop-|x-|vendor\\.)": {
|
|
77
|
+
"description": "Vendor / host extension escape hatch (RFC 0138). A property matching `^(x-|vendor\\.)` is a HOST EXTENSION: its semantics are unspecified by this protocol, and a consumer that does not recognize one MUST ignore it rather than reject the pack. Resolves the contradiction in `host-extensions.md` §\"Vendor-prefixed namespaces\", which requires a client receiving an unknown vendor-prefixed field to treat it as opaque — a field that `additionalProperties: false` previously made impossible to carry. SECURITY: an extension value is PACK-AUTHORED, therefore untrusted; \"ignore\" means ignore. See `node-packs.md` §\"Vendor extensions on pack manifests\" and the `pack-manifest-extension-opaque` invariant."
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"$defs": {
|
|
81
|
+
"uiPlugin": {
|
|
82
|
+
"type": "object",
|
|
83
|
+
"required": [
|
|
84
|
+
"pluginId",
|
|
85
|
+
"surface",
|
|
86
|
+
"entry",
|
|
87
|
+
"hostApi"
|
|
88
|
+
],
|
|
89
|
+
"additionalProperties": false,
|
|
90
|
+
"properties": {
|
|
91
|
+
"pluginId": {
|
|
92
|
+
"$ref": "ids.schema.json#/$defs/pluginId",
|
|
93
|
+
"description": "Stable identifier of this plugin within the pack. A host enables/disables plugins by `pluginId` in its admin surface."
|
|
94
|
+
},
|
|
95
|
+
"surface": {
|
|
96
|
+
"type": "string",
|
|
97
|
+
"description": "Which host surface this plugin renders into. `artifact-viewer` renders a typed artifact (RFC 0071) in a sandbox; `route` mounts a standalone admin/tool page; `settings-panel` contributes a configuration panel; `canvas-preview` renders the live document preview inside a host-owned canvas editor (RFC 0130). A host degrades a `surface` it does not advertise to nothing (§Degradation).",
|
|
98
|
+
"enum": [
|
|
99
|
+
"artifact-viewer",
|
|
100
|
+
"route",
|
|
101
|
+
"settings-panel",
|
|
102
|
+
"canvas-preview"
|
|
103
|
+
]
|
|
104
|
+
},
|
|
105
|
+
"entry": {
|
|
106
|
+
"type": "string",
|
|
107
|
+
"description": "Pack-relative path to the plugin's entry bundle (the opaque bytes loaded in the cross-origin sandbox). Flat namespace; MUST NOT contain `..` or a leading `/` (the pattern forbids both). Required — a `uiPlugins[]` entry missing `entry` fails validation (RFC 0117 §Negative).",
|
|
108
|
+
"pattern": "^[A-Za-z0-9][A-Za-z0-9._/-]{0,255}$"
|
|
109
|
+
},
|
|
110
|
+
"hostApi": {
|
|
111
|
+
"type": "array",
|
|
112
|
+
"description": "The closed allowlist of `ui-plugin/1` host-RPC methods this plugin is permitted to call. The host MUST reject (with an `error` response, never silent execution) any method not in BOTH this declared list AND the host's `capabilities.uiPlugins.hostApi` set (`frontend-plugin-rpc-allowlist`). The plugin holds no credentials; every method is host-mediated and authz-checked.",
|
|
113
|
+
"items": {
|
|
114
|
+
"type": "string",
|
|
115
|
+
"enum": [
|
|
116
|
+
"artifact.read",
|
|
117
|
+
"artifact.write",
|
|
118
|
+
"host.toast",
|
|
119
|
+
"host.navigate",
|
|
120
|
+
"host.announce"
|
|
121
|
+
]
|
|
122
|
+
},
|
|
123
|
+
"uniqueItems": true
|
|
124
|
+
},
|
|
125
|
+
"canvasTypes": {
|
|
126
|
+
"type": "array",
|
|
127
|
+
"description": "OPTIONAL; meaningful only for `surface: \"canvas-preview\"` (RFC 0130): the host canvas type id(s) this preview renders. A host mounts the plugin only for matching canvas documents and MUST ignore entries it does not recognize; absent/empty means never auto-mounted.",
|
|
128
|
+
"items": {
|
|
129
|
+
"type": "string",
|
|
130
|
+
"maxLength": 128
|
|
131
|
+
},
|
|
132
|
+
"uniqueItems": true
|
|
133
|
+
},
|
|
134
|
+
"connectSrc": {
|
|
135
|
+
"type": "array",
|
|
136
|
+
"description": "OPTIONAL explicit `connect-src` CSP exceptions the plugin needs (e.g., a font CDN). Absent → the host serves the plugin under a DENY-EGRESS CSP (`frontend-plugin-egress`): no network egress beyond the host-RPC channel. Any entry here is part of the front-end-review checkpoint (`registry-operations.md`) a reviewer audits; a host MAY refuse a pack whose exceptions it will not grant.",
|
|
137
|
+
"items": {
|
|
138
|
+
"type": "string",
|
|
139
|
+
"format": "uri"
|
|
140
|
+
},
|
|
141
|
+
"uniqueItems": true
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
"patternProperties": {
|
|
145
|
+
"^(openwop-|x-|vendor\\.)": {
|
|
146
|
+
"description": "Vendor / host extension escape hatch (RFC 0138). A property matching `^(x-|vendor\\.)` is a HOST EXTENSION: its semantics are unspecified by this protocol, and a consumer that does not recognize one MUST ignore it rather than reject the pack. Resolves the contradiction in `host-extensions.md` §\"Vendor-prefixed namespaces\", which requires a client receiving an unknown vendor-prefixed field to treat it as opaque — a field that `additionalProperties: false` previously made impossible to carry. SECURITY: an extension value is PACK-AUTHORED, therefore untrusted; \"ignore\" means ignore. See `node-packs.md` §\"Vendor extensions on pack manifests\" and the `pack-manifest-extension-opaque` invariant."
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
"x-openwop-seeded-from": "v1"
|
|
152
|
+
}
|