# Plugin SDK Go module `git.dev.alexdunmow.com/block/pluginsdk`. **Purpose: this is the ONE plugin-facing artifact.** BlockNinja CMS plugins import this module and nothing else from the internal Go tree. Plugins must NOT import `block/core` — core exists only for code shared between first-party entities (cms, orchestrator, ninja CLI). ## The contract is proto, not Go - `abi/proto/v1/*.proto` is **the contract**. The host↔guest wire is proto-only; a plugin in ANY language generates its own bindings from these files. - `abi/v1/` is the **Go** binding of that contract (`abiv1`). The rest of the Go surface here — `plugin/`, `plugin/wasmguest/**`, and the guest-facing type packages — is **one language binding** of the SDK. A non-Go plugin implements the ABI hooks directly and never sees these Go structs. ## Critical Rules - **NEVER use `replace` directives in go.mod** — not here, not in any consumer. All module resolution goes through the Gitea module proxy. To test local changes, tag and push a version. - All consumers are in-house — **no backwards-compatibility shims**. Change the API and update consumers. - Regenerate Go bindings after editing any `.proto`: `make proto`. ## `templates/bn/` is a synced copy — do not author here The bn page chrome (head / toolbar / engagement / asset_hooks) is **authored in `cms/backend/templates/bn`** and mechanically copied here via cms `make sync-templates`, solely so guest-side plugin templates can compile it into their wasm. check-safety **check 31** fails cms commits while the copies drift. Never edit these files here directly — change them in cms and sync. (This chrome is transitional: it is deleted once host-side head/body injection lands — Phase 3.) ## Design Program spec (in the cms repo): `docs/superpowers/specs/2026-07-07-proto-first-plugin-sdk-design.md`.