Files
OwnCord/Server/plugin/examples/hello/README.md
T

94 lines
4.6 KiB
Markdown
Raw Normal View History

# hello plugin
Phase C Step 9 — a worked reference implementation of the plugin ABI, and the
manifest the loader parses. Source only: the `.wasm` is not checked in.
> **The plugin ABI is experimental and carries no compatibility promise.** The
> subsystem is disabled twice over — it compiles only under `-tags wazero`
> (`Server/plugin/sandbox_default.go`), and `plugins.enabled` defaults to
> `false` (`Server/config/config.go`) — and the five exported functions may
> change or be removed in any release without a deprecation period.
## Manifest
`plugin.json` declares the `commands`, `events`, and `storage` capabilities.
The manifest is the only file the default (no-`-tags wazero`) build needs —
the registry persists it into the plugins table without executing the .wasm.
The `commands` block is the per-command ACL: activation binds only the names
listed there, so `list_commands` returning anything else is ignored. Keep
`plugin.json`'s list and `listCommandsJSON` in `main.go` in sync — a name in
the WASM but not the manifest simply never binds.
## Building the WASM
2026-04-07 10:13:47 +02:00
`main.go` in this directory implements the full plugin ABI
(`allocate`, `deallocate`, `list_commands`, `command_dispatch`, `on_event`).
Build it before pointing a plugin directory at this example — `hello.wasm` is
gitignored and produced locally, not distributed.
2026-04-07 10:13:47 +02:00
### Prerequisites
This table is the single source of truth for the plugin toolchain;
`docs/contributing.md` links here rather than repeating it.
| Tool | Version | Notes |
| -------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| TinyGo | 0.40.1 | Supports Go 1.191.25 only |
| Go | 1.25.x | TinyGo 0.40.1 rejects Go 1.26+. Install alongside the system Go: `go install golang.org/dl/go1.25.3@latest && go1.25.3 download` |
| wasm-opt | Binaryen 129 | Required by TinyGo for the `wasi` target; download from Binaryen GitHub releases |
Note the Go row: this repository's own module is pinned to Go 1.26
(`Server/go.mod`), so building a plugin needs a _second_, older Go SDK
side-installed. That conflict is why there is no CI job for this — see
Provenance.
2026-04-07 10:13:47 +02:00
On Windows, extract TinyGo to e.g. `D:\Local-Lab\Coding\Software\tinygo` and
add `<tinygo>\bin` plus `<binaryen>\bin` to `PATH`. Then point TinyGo at the
compatible Go SDK:
```pwsh
$env:GOROOT = "$env:USERPROFILE\sdk\go1.25.3" # installed via: go install golang.org/dl/go1.25.3@latest
$env:PATH = "$env:GOROOT\bin;$env:PATH"
```
2026-04-07 10:13:47 +02:00
### Build command
```sh
# Run from this directory (Server/plugin/examples/hello/)
tinygo build -o hello.wasm -target wasi ./main.go
```
Any WASM toolchain (Rust/`wasm32-wasi`, AssemblyScript, …) that exports the five
ABI functions is equally valid. TinyGo is just the toolchain this example uses.
## Provenance
The `.wasm` that used to be committed here was produced by **TinyGo 0.40.1 with
Go 1.25.3 and Binaryen 129**, on Windows. It was removed in B1-6 (RL-08).
It is **not byte-reproducible**, and that is why no CI job compiles and compares
it: TinyGo embeds absolute host paths from the building machine's Go SDK and
module cache into its output, and offers no `-trimpath` equivalent. Two
machines building the same source produce different bytes, so a byte-identity
gate cannot pass in principle — not merely "is unbuilt". BPR-080 asks that the
example WASM be _reproducible or provenance-verified_; this section is the
second branch.
A compile-only drift check would still be possible, but it needs three pinned
downloads (TinyGo, a second Go SDK, Binaryen) on every PR for a subsystem that
is disabled at compile time _and_ at runtime. That is deferred to B2, which the
issue register already names as L-08's second phase.
## Tests
Nothing in the Go build or test graph reads this directory. `main.go` carries
`//go:build tinygo`, so `go list ./plugin/...` returns one package with and
without `-tags wazero`, and `examples/hello` is not in it.
The plugin tests build their own fixtures instead: `plugin_test.go` writes
manifests and stub bytes into `t.TempDir()`, and `sandbox_wazero_test.go` uses a
41-byte inline WASM literal — with the comment _"Using a literal here avoids
dragging a binary asset into the repo."_ That call was already made for the test
suite; RL-08 extends it to the example.