MediaValue gains an Attribution credit resolved through the existing
MediaResolver context hook. The BlockNote image case renders width and
align presets, alt text, an optional link wrap, and the attribution chip
in chip, chipHover, and below modes with the same themed markup as the
cms page-builder image block. Legacy url-and-caption blocks render
byte-identical to the previous output.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Host-mediated outbound HTTP for wasm plugins: guest http.RoundTripper
over the http.request capability; the host performs the request under
policy. New egress package defines the host-pattern grammar (exact or
multi-label wildcard, public-suffix rejected), matching, resource
bounds, and the ErrDenied sentinel (ABI_ERROR_CODE_EGRESS_DENIED).
plugin.mod gains first-class AllowedHosts + MaxResponseMB; manifest
gains allowed_hosts=34, max_response_mb=35. CoreServices.OutboundHTTP
carries the transport. Golden roundtrip + denial-mapping tests.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The cms host parity gate replays these goldens; the capability landed
in v0.2.3 without them, so hosts on v0.2.3 fail TestGoldenParity —
pin v0.2.4 instead.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds content.published_block_configs: the host returns the stored
content JSON of every block with a given key inside currently
published page snapshots. Restores server-authoritative per-block
enforcement for sandboxed guests (calcomblock's captcha requirement
was inert under wasm — blockConfig hardcoded nil because no capability
exposed published block content). Breaking: content.Content gains a
method; the cms adapter implements it in the paired bump.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The host verifies (and consumes) a request's cap-token against its
stateful captcha server before wasm dispatch and stamps this header;
guests enforce captcha by checking CaptchaVerified, fail closed.
Included in AllTrustedHeaders so the host's strip-then-stamp loop
makes it unforgeable, like the identity headers.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copy core@v0.20.3 render/blocknote.go (+ tests) with the blocks import
repointed to pluginsdk/blocks, so GetEmbedResolver/GetHumanProofBanner
read the same context keys the pluginsdk bridge writes. Fixes empty
embeds and missing human-proof banners in hosts that inject render
state via pluginsdk/blocks context.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The README/AGENTS prose mentioned the literal `block/core` token when stating
that plugins must not import it. Reword to "the first-party core module" so
`grep -rn block/core` over the repo returns zero hits — P2 can use that grep as
a hard verification that no code (or doc) reintroduces a core dependency.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bootstrap the plugin-facing SDK module so the fleet migration (P2) becomes a
mechanical block/core/X -> block/pluginsdk/X import rewrite.
- abi/proto/v1: the single source-of-truth ABI proto tree, copied from the cms
authoring source (cms/backend/abi/proto/v1) with go_package retargeted to
git.dev.alexdunmow.com/block/pluginsdk/abi/v1;abiv1. Kills the hand-kept
cms/core proto duplication (audit gap 4).
- abi/v1: generated Go bindings (buf generate); byte-identical to core's abi/v1
save the embedded go_package path.
- plugin/ (registration + DI surface), plugin/wasmguest/** (transport shim,
caps stubs, bnwasm db driver, testdata fixtures + golden .pb), and the
guest-facing type packages: blocks (+builtin/shared/tags), templates
(+pongo/bn), auth, settings, content, gating, crypto, rbac, video, ai,
subscriptions, menus, datasources. Internal imports rewritten core ->
pluginsdk; zero block/core references remain.
- README/AGENTS(+CLAUDE symlink)/Makefile: proto is the contract, Go is one
binding; no replace directives; templates/bn is a synced copy authored in cms.
Spec: cms docs/superpowers/specs/2026-07-07-proto-first-plugin-sdk-design.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>