Skip to content

Commit 56577f9

Browse files
committed
docs(rfc): address hosted feed review comments
1 parent da91683 commit 56577f9

1 file changed

Lines changed: 121 additions & 72 deletions

File tree

rfcs/0009-hosted-feeds-for-plugins-and-skills.md

Lines changed: 121 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ authors:
55
- Patrick
66
- Gio
77
created: 2026-06-18
8-
last_updated: 2026-06-20
8+
last_updated: 2026-06-22
99
status: draft
1010
issue:
1111
rfc_pr: https://github.com/openclaw/rfcs/pull/19
@@ -16,12 +16,14 @@ rfc_pr: https://github.com/openclaw/rfcs/pull/19
1616
## Summary
1717

1818
Define a hosted feed model for OpenClaw plugins and skills. A feed is a JSON
19-
catalog document that describes available packages, named local package sources,
20-
version and integrity metadata, and feed-level governance state such as
21-
recommended, disabled, blocked, or update available. OpenClaw should move the
22-
existing file-backed external plugin catalog to this feed model first, keep a
23-
bundled fallback for offline environments, and later extend the same contract to
24-
skills and organization-specific catalogs.
19+
catalog document that describes available packages, version and integrity
20+
metadata, package-source references, and feed-level governance state such as
21+
recommended, disabled, blocked, or update available. A package-source reference
22+
is a name that the local OpenClaw deployment maps to npm, ClawHub, Git, or a
23+
private registry configuration. OpenClaw should move the existing file-backed
24+
external plugin catalog to this feed model first, keep a bundled fallback for
25+
offline environments, and later extend the same contract to skills and
26+
organization-specific catalogs.
2527

2628
The first implementation should preserve the package model OpenClaw already
2729
uses. External plugins can continue to install from npm or ClawHub, with Git
@@ -66,17 +68,19 @@ package source layer.
6668
- Define immutable Git source installs using full commit hashes.
6769
- Define a feed entry shape for plugins first, with room for skills and other
6870
package types.
69-
- Support edge-hosted and regional feeds so provider availability can differ by
70-
geography or deployment environment.
71+
- Support edge-hosted feed variants so provider availability can differ by
72+
geography or deployment environment without requiring clients to interpret a
73+
complex regional policy language.
7174
- Let ClawHub publish one or more public feeds for OpenClaw clients.
7275
- Let enterprises publish composed effective feeds that subset, block, pin, or
7376
augment public feeds.
7477
- Support private organization and team feeds without forcing OpenClaw to own
7578
the private registry RBAC model.
7679
- Let clients check feeds on a named, lifecycle-owned refresh schedule using
7780
HTTP `Last-Modified` and `ETag`.
78-
- Support signed remote feeds and an optional, small trust envelope for signing
79-
key rotation without requiring a full update framework in the first version.
81+
- Support signed remote feeds with directly configured publisher keys first,
82+
while leaving room for a later signed key-rotation document if ClawHub needs
83+
remote publisher-key rotation.
8084
- Keep a bundled feed in every OpenClaw build so offline, Docker, and
8185
air-gapped environments continue to work.
8286
- Create an RFC and implementation plan that ClawHub, Microsoft, Tencent,
@@ -105,8 +109,11 @@ OpenClaw should treat feeds as the catalog primitive underneath plugin and skill
105109
marketplace experiences. A feed is fetched from an HTTP endpoint or loaded from a
106110
local file. The client validates the document shape, verifies a configured
107111
signature policy when present, and uses entry-level package metadata to drive
108-
search, recommendation, install, update notices, and feed-level allow/block
109-
decisions.
112+
recommendations, installs, update notices, and feed-level allow/block decisions.
113+
Registry-owned search can still remain with ClawHub or another marketplace
114+
service. In that model the registry returns ranked results, and the OpenClaw
115+
client filters or annotates those results against the configured feeds before
116+
showing or installing them.
110117

111118
The initial implementation should refactor the existing external plugin catalog
112119
rather than introduce a parallel catalog. Today the relevant OpenClaw entry
@@ -126,8 +133,15 @@ source from bundled-only JSON to hosted JSON with bundled fallback.
126133

127134
A feed document should be a deterministic JSON document with a schema version,
128135
feed id, generated timestamp, monotonic sequence number, expiry, and entries.
129-
Entry ids must be stable. Entries select a configured local source by name rather
130-
than embedding a registry domain, credentials, or trust roots.
136+
Entry ids must be stable registry identities, not mutable display slugs. If a
137+
registry allows user-editable slugs, the feed should either carry an immutable
138+
package id or use the canonical package coordinate as the stable id. Display
139+
slugs and titles can still appear as metadata, but installs and policy decisions
140+
should not depend on them. Publisher trust should start with ClawHub's current
141+
binary distinction of official or not official, rather than inventing reviewed or
142+
verified publisher labels in the first feed. Entries select a configured local
143+
source by name using `sourceRef` rather than embedding a registry domain,
144+
credentials, or trust roots.
131145

132146
```jsonc
133147
{
@@ -156,9 +170,6 @@ than embedding a registry domain, credentials, or trust roots.
156170
"integrity": "sha512-..."
157171
}
158172
]
159-
},
160-
"regions": {
161-
"include": ["global"]
162173
}
163174
}
164175
]
@@ -168,22 +179,30 @@ than embedding a registry domain, credentials, or trust roots.
168179
The initial states should cover the known plugin catalog needs:
169180

170181
- `available`: entry can be shown and installed.
171-
- `recommended`: entry can be highlighted in onboarding or search.
172-
- `disabled`: entry is known but not currently installable from this feed.
173-
- `blocked`: entry should not be installed through this feed.
182+
- `recommended`: entry can be highlighted by a client or tenant overlay, but it
183+
should not replace a registry-owned search ranking by itself.
184+
- `disabled`: entry is known but intentionally not offered for new install from
185+
this feed. This is useful for temporary availability, rollout, or regional
186+
reasons where the package may still exist elsewhere.
187+
- `blocked`: entry is an explicit deny decision. A composed feed can use this to
188+
remove or override an entry inherited from a parent feed.
174189
- `deprecated`: entry remains visible for migration but should not be selected
175190
for new installs.
176191

177192
The exact enum names can change during implementation, but the RFC should keep
178193
these concepts separate. A recommended package is not the same as a merely
179-
available package. A disabled package is not the same as a blocked package.
194+
available package. A disabled package is not the same as a blocked package:
195+
`disabled` means unavailable from this feed, while `blocked` means explicitly
196+
denied by this feed.
180197

181198
### Local feed and source configuration
182199

183200
Feed names and source profile names are deployment-local. There is no
184201
`enterprise` feed or registry shape. A deployment can name feeds and sources
185202
after its own topology, while a feed entry refers only to a configured
186-
`sourceRef`.
203+
`sourceRef`. For example, `public-npm` is not a domain from the feed. It is a
204+
local profile that OpenClaw resolves to an npm registry URL, credentials, and
205+
installer behavior already trusted by that deployment.
187206

188207
```jsonc
189208
{
@@ -274,6 +293,13 @@ same discovery contract, but skill installation remains staged until the native
274293
skill installer accepts catalog candidates. A ClawHub skill must not be routed
275294
through the plugin installer merely because both appear in a feed.
276295

296+
Skills also need extra care because the Agent Skills specification does not
297+
require a version, and ClawHub can index skills that are installed directly from
298+
GitHub rather than mirrored by ClawHub. A feed candidate for such a skill should
299+
be allowed to point at an approved GitHub source profile with `repo`, `path`, a
300+
full commit hash, and a content hash. The feed should not assume every skill has
301+
a ClawHub-hosted package artifact or a semantic version.
302+
277303
### Feed discovery and fallback
278304

279305
OpenClaw should have a default feed URL for the ClawHub public feed. At build or
@@ -319,8 +345,9 @@ threshold are the initial trust anchor; a remote feed cannot bootstrap or replac
319345
them. `verification.mode: "signed"` fails closed. An unsigned HTTPS feed requires
320346
the explicit local `verification.mode: "unsigned"` opt-in.
321347

322-
Most feeds can use directly configured public keys. When remote signing-key
323-
rotation is needed, the same envelope format can wrap a small trust document:
348+
Most feeds can use directly configured public keys. That should be the first
349+
implementation. If ClawHub later needs remote signing-key rotation, the same
350+
envelope format can wrap a small signed key-rotation document:
324351

325352
```jsonc
326353
{
@@ -334,14 +361,15 @@ rotation is needed, the same envelope format can wrap a small trust document:
334361
}
335362
```
336363

337-
The configured root-key quorum verifies the trust envelope. The verified
338-
`feedKeys` quorum then verifies feed envelopes. A trust update must be signed by
339-
the currently trusted root quorum, and the client persists the accepted sequence
340-
and expiry to reject rollback and freeze attempts. Root-key replacement remains a
341-
local operator action for emergency recovery. The bundled fallback is trusted as
342-
part of the shipped OpenClaw artifact, not as an unsigned replacement for a
343-
configured signed remote feed. `verification.trustUrl` is optional; when absent,
344-
the configured root keys directly verify feed envelopes.
364+
If key rotation is enabled, a locally configured root-key quorum verifies the
365+
signed key-rotation document. The verified `feedKeys` quorum then verifies feed
366+
envelopes. A key-rotation update must be signed by the currently trusted root
367+
quorum, and the client persists the accepted sequence and expiry to reject
368+
rollback and freeze attempts. Replacing root keys remains a local operator action
369+
for emergency recovery. The bundled fallback is trusted as part of the shipped
370+
OpenClaw artifact, not as an unsigned replacement for a configured signed remote
371+
feed. `verification.trustUrl` is optional; when absent, the configured local keys
372+
directly verify feed envelopes.
345373

346374
```mermaid
347375
flowchart LR
@@ -390,6 +418,16 @@ parent feed and apply local rules: include only some entries, block entries,
390418
change recommendation state, pin versions, add private entries, or publish a
391419
regional variant.
392420

421+
When multiple feeds or overlays mention the same stable entry id, the effective
422+
state should be deterministic. The recommended first resolution order is:
423+
`blocked` wins over every other state, then `disabled`, then `deprecated`, then
424+
`recommended`, then `available`. Pinning a version or adding a private candidate
425+
should not override a `blocked` decision unless the composing system explicitly
426+
removes the block before publishing the final effective feed. ClawHub can ignore
427+
recommendation overrides in its own public search ranking, while enterprises can
428+
use recommendation and pinning metadata as tenant-local ranking or onboarding
429+
overrides.
430+
393431
The screen-share model from the design discussion used `register.openclaw.ai` as
394432
the public OpenClaw feed endpoint and a tenant endpoint such as
395433
`tenant.msft.azure.example` as a composed feed. Those names are illustrative,
@@ -434,9 +472,16 @@ their own registry, CI job, private Git repository, or static hosting service.
434472

435473
The feed model should allow regional variants. Some providers are only useful in
436474
certain markets. Some providers may be unavailable or blocked in certain regions.
437-
The feed endpoint can use edge routing, or the client can be configured with an
438-
explicit regional feed URL. The feed document should make regional intent visible
439-
so reviewers and mirrors can reason about it.
475+
The simplest model is for ClawHub or a mirror to publish separate effective feed
476+
documents per region and cache those documents at the edge. A client can then use
477+
edge routing or an explicit configured regional feed URL. This avoids requiring
478+
the first client to evaluate a complex `regions` field at install time.
479+
480+
A feed document may still carry human-readable regional metadata for review and
481+
mirror operations, but regional selection should initially be a feed-selection
482+
problem rather than a per-entry policy language. The bundled fallback can remain
483+
global; if a distribution needs an offline regional fallback, it can bundle that
484+
regional feed variant in its own build.
440485

441486
```mermaid
442487
flowchart TD
@@ -499,60 +544,64 @@ from richer systems such as ClawHub, MOS3, private Git repositories, or CI jobs.
499544

500545
This proposal deliberately separates the feed from package storage and source
501546
configuration. npm already solves package distribution for current external
502-
plugins. ClawHub can remain the public registry and package discovery surface.
503-
Organizations can keep private artifacts in their own registries or Git hosts.
504-
The feed only selects approved package candidates and records immutable
505-
integrity data; local source profiles decide where those candidates resolve and
506-
how the client authenticates.
507-
508-
The trust envelope is intentionally smaller than a full updater framework.
509-
Directly configured keys cover the normal case. The optional trust document adds
510-
remote publisher-key rotation and expiry without making the first implementation
511-
own generic delegation, mirror, or artifact-update roles.
547+
plugins. ClawHub can remain the public registry, marketplace, and package
548+
discovery surface, including ownership of its own search algorithm. Organizations
549+
can keep private artifacts in their own registries or Git hosts. The feed only
550+
selects approved package candidates and records immutable integrity data; local
551+
source profiles decide where those candidates resolve and how the client
552+
authenticates.
553+
554+
The signed envelope is intentionally smaller than a full updater framework.
555+
Directly configured publisher keys cover the normal case and should be enough for
556+
the first release. If ClawHub later needs remote publisher-key rotation, a
557+
separate signed key-rotation document can describe the currently valid feed
558+
signing keys and expiry. That follow-up should be treated as a distinct design
559+
step, not as a requirement for the first hosted feed.
512560

513561
The bundled fallback is not optional. Without it, a feed outage or blocked
514562
endpoint would break onboarding and plugin discovery. With it, hosted feeds add
515563
freshness and control while preserving today’s offline behavior.
516564

517565
## Rollout plan
518566

519-
1. Refactor the existing external plugin manifest so the current local catalog
567+
1. Align on the RFC enough to proceed with implementation, including source
568+
profile terminology, search ownership, state precedence, signing scope, and
569+
the plugin-first rollout boundary.
570+
2. Refactor the existing external plugin manifest so the current local catalog
520571
shape can be generated from a feed document.
521-
2. Add named feed and source profiles, including npm registry overrides,
572+
3. Add named feed and source profiles, including npm registry overrides,
522573
ClawHub-compatible base URLs, Git base paths, and secret-reference
523574
authentication.
524-
3. Publish the first ClawHub-hosted feed for the existing official external
525-
plugins.
526-
4. Update OpenClaw to load the bundled fallback, refresh hosted feeds after
575+
4. Add signed feed envelopes with directly configured keys for public hosted
576+
feeds. Self-hosted unsigned HTTPS feeds remain an explicit local opt-in.
577+
5. Publish the first ClawHub-hosted feed for the current external plugin catalog.
578+
The first feed may include all current external entries; ClawHub can narrow
579+
future default feeds to official packages as the official catalog grows.
580+
6. Update OpenClaw to load the bundled fallback, refresh hosted feeds after
527581
gateway startup, and store verified snapshots in SQLite.
528-
5. Add conditional HTTP update detection with `ETag` and `Last-Modified`.
529-
6. Add signed feed envelopes with directly configured keys, then add the
530-
optional rotating trust envelope when publisher-key rotation is required.
531-
7. Add regional feed support once the default hosted feed path is stable.
532-
8. Extend the same discovery contract to skills after the skill installer
533-
accepts catalog candidates.
534-
9. Add composition guidance and examples for Microsoft/MOS3 and other
535-
tenant-admin systems.
536-
10. Align Tencent, Xiaomi, and other regional mirrors before the spec is treated
582+
7. Add conditional HTTP update detection with `ETag` and `Last-Modified`.
583+
8. Add regional feed variants once the default hosted feed path is stable.
584+
9. Extend the same discovery contract to skills after the skill installer
585+
accepts catalog candidates, including GitHub-indexed skills that do not have
586+
ClawHub-hosted artifacts.
587+
10. Add composition guidance and examples for Microsoft/MOS3 and other
588+
tenant-admin systems.
589+
11. Align Tencent, Xiaomi, and other regional mirrors before the spec is treated
537590
as stable.
591+
12. Land implementation through small draft PRs that maintainers can review,
592+
adjust, and merge as the RFC stabilizes.
538593

539594
## Unresolved questions
540595

541-
- Should the default ClawHub feed include only official entries, reviewed
542-
entries, trusted publisher entries, or several named feeds?
543596
- Which `npm`, `clawhub`, and `git` source-profile fields should become stable
544597
user configuration, and which should remain installer implementation details?
545-
- Should regional selection be client-configured, edge-routed, tenant-driven, or
546-
a combination?
547-
- What user-facing noun should OpenClaw use: feed, marketplace, registry, or
548-
another term?
549-
- Should a signed public feed be required from the first release, or should
550-
unsigned HTTPS feeds remain an explicit opt-in for self-hosted deployments?
551-
- When should the optional trust envelope be introduced, and do public feeds need
552-
separate offline root keys from online publisher keys from day one?
598+
- Should regional selection be edge-routed, explicit-feed configured,
599+
tenant-driven, or a combination after the first global feed works?
600+
- Should OpenClaw use "marketplace" for the user-facing surface and reserve
601+
"feed" for the protocol and propagation artifact?
553602
- Which runtime policy metadata should feed entries be allowed to reference
554603
without turning the feed into a policy engine?
555604
- How many stable OpenClaw releases should ship hosted feed fallback before
556605
Scout, Microsoft, and other clients depend on the contract?
557-
- How should ClawHub represent trusted, verified, official, and reviewed
558-
publishers in the public feed?
606+
- Should a later LTS release define stronger compatibility guarantees for feed
607+
schema versions and fallback behavior?

0 commit comments

Comments
 (0)