Registry contract v2: WebAssembly plugins with release assets - #5
Conversation
The directory now only lists WebAssembly plugins. The manifest requires runtime "wasm", its entry names a .wasm release asset (default plugin.wasm) and may declare allowed_hosts; ValidateEntry downloads the asset attached to the latest release (16 MiB cap), runs goblog's validate-plugin on it in the Docker sandbox and requires runtime "wasm" back. The index carries download_url as the asset's browser URL, sha256 of the asset, install_type/runtime "wasm" and allowed_hosts (always an array, never null). The image pin moves to compscidr/goblog:v0.2.9. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
CONTRACT.md now describes what a wasm plugin repository must contain, the manifest's runtime, entry and allowed_hosts fields and what they mean, the release workflow that builds and attaches plugin.wasm, a summary of the host contract with a link to goblog's README, and the local validate-plugin check against the v0.2.9 image. It says plainly that Yaegi .go plugins are not accepted. README and the submission issue form describe the new index fields and release asset. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A glob made only of "*" and "." names no host and would let a plugin reach anything; the registry is the curation point, so ParseManifest rejects it with a message that says so (globs that name a domain, such as *.example.test, stay accepted). ValidateEntry stops at the first asset whose name matches the entry. TestDefaultImage goes: validator_test already pins the image and is in Renovate's file list, so the extra guard would only break Renovate bumps. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The updated documentation contains a few contract mismatches (asset name and LICENSE requirement) that could mislead plugin authors and should be corrected before approval.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 3
Open (3)
What changed in this PR
This PR updates the plugin registry contract and implementation to support WebAssembly-only goblog plugins distributed as GitHub release assets, and updates validation, indexing, docs, and CI defaults accordingly.
Changes:
- Moves plugin validation from repo source files to downloading and validating the release asset named by
goblog-plugin.jsonentry(defaultplugin.wasm), enforcingruntime: "wasm". - Extends registry data model and index/detail JSON to include release assets (
download_url,sha256,runtime,allowed_hosts,install_type: "wasm"). - Updates docs, workflows, and tests to the new WebAssembly contract and
compscidr/goblog:v0.2.9.
| File | Description |
|---|---|
| README.md | Updates top-level registry description for wasm assets and new index fields. |
| internal/registry/validator.go | Switches Docker validation input from plugin.go to plugin.wasm and adds runtime to identity. |
| internal/registry/validator_test.go | Updates validator tests for wasm modules and adds coverage for writing plugin.wasm. |
| internal/registry/validate.go | Resolves and downloads the release asset by name/ID and enforces runtime == "wasm". |
| internal/registry/validate_test.go | Updates validation tests to model release assets and asset download errors/limits. |
| internal/registry/source.go | Adds release asset model + download API with size cap. |
| internal/registry/source_test.go | Adds tests for release asset listing and download/size limit behavior. |
| internal/registry/manifest.go | Introduces manifest v2 fields (runtime, allowed_hosts), defaults, and validation rules. |
| internal/registry/manifest_test.go | Updates and extends manifest validation tests for wasm + allowed_hosts. |
| internal/registry/build.go | Publishes asset download_url, plus runtime/install_type/allowed_hosts in index/detail docs. |
| internal/registry/build_test.go | Updates build tests for wasm index/detail output and non-null allowed_hosts. |
| docs/CONTRACT.md | Rewrites publishing contract for WebAssembly-only plugins with release assets. |
| cmd/registry/main.go | Bumps default validation image to compscidr/goblog:v0.2.9. |
| cmd/registry/main_test.go | Updates CLI tests for wasm runtime and release assets. |
| .github/workflows/validate.yml | Bumps validation workflow image to v0.2.9. |
| .github/workflows/submit.yml | Bumps submission workflow image to v0.2.9. |
| .github/workflows/publish.yml | Bumps publish workflow image to v0.2.9. |
| .github/ISSUE_TEMPLATE/submit-plugin.yml | Updates submission instructions for wasm contract and release assets. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
|
||
| - `registry.yaml` — the list. Submit your repository via the [issue form](.github/ISSUE_TEMPLATE/submit-plugin.yml) (a pull request by hand is the alternative); see [docs/CONTRACT.md](docs/CONTRACT.md). | ||
| - `https://goblogplatform.github.io/plugins/index.json` — the machine-readable index (latest release of each plugin, with `download_url` and `sha256`) and `stars` (GitHub stargazers, the directory's default ordering); `plugins/<name>.json` adds the rendered README, changelog and release history. | ||
| - `https://goblogplatform.github.io/plugins/index.json` — the machine-readable index: the latest release of each plugin, with `download_url` (the `plugin.wasm` release asset) and its `sha256`, `runtime` and `install_type` (both `wasm`), `allowed_hosts` (the network the module may reach; `[]` for none) and `stars` (GitHub stargazers, the directory's default ordering); `plugins/<name>.json` adds the rendered README, changelog and release history. |
There was a problem hiding this comment.
Reworded in 4b2d494: download_url is the release asset named by the manifest's entry (plugin.wasm by default), in both places the README said plugin.wasm.
| ## What the directory publishes | ||
|
|
||
| The index entry for your plugin is built from the manifest, the latest release, and your repository's GitHub star count (`stars`), which the directory uses for its default ordering. Stars are best-effort: if GitHub cannot be reached for them, the entry is published with `0`. | ||
| The index entry for your plugin is built from the manifest, the latest release and its `plugin.wasm` asset (`download_url` is the asset's browser URL; `sha256` is of the asset), and your repository's GitHub star count (`stars`), which the directory uses for its default ordering. Stars are best-effort: if GitHub cannot be reached for them, the entry is published with `0`. The entry also carries `runtime: "wasm"`, `install_type: "wasm"` and the manifest's `allowed_hosts`, which goblog's admin page shows as "Talks to: …" before an operator installs. |
There was a problem hiding this comment.
Reworded in 4b2d494 to "its module asset (the one named by entry, plugin.wasm by default)".
…d, not validated Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Summary
The directory now lists WebAssembly plugins only (spec: goblog
docs/superpowers/specs/2026-09-18-wasm-plugins-design.md§3).goblog-plugin.jsonv2:runtime: "wasm"(required),entry= the.wasmrelease asset name (defaultplugin.wasm), optionalallowed_hosts(validated; all-wildcard entries refused). Yaegi.goentries are rejected with a pointer todocs/CONTRACT.md.Source.ReleaseAsset+Release.Assets;ValidateEntrydownloads the named asset (≤ 16 MiB, size-checked before and during download) and validates it withgoblog validate-plugin plugin.wasmin thecompscidr/goblog:v0.2.9sandbox; identity must reportruntime: wasm.download_urlis the asset's browser URL,sha256of the asset, plusruntime,allowed_hosts(never null),install_type: "wasm".allowed_hostssemantics); issue template wording updated.Validated against the live
goblogplatform/goblog-plugin-hellov2.0.0:build→hello 2.0.0 wasm, indexsha256=f04d6cc9…=sha256sumof the downloaded asset.After merge,
Publish indexrepublishes; goblog ≥ 0.2.9 installs from Admin → Plugins.🤖 Generated with Claude Code