Skip to content

plugin

Recipe card from the charly-internals plugin (Development — contributor internals).

This card has additional detail pages:

Plugins — the unified Provider + per-plugin CUE-schema model

Section titled “Plugins — the unified Provider + per-plugin CUE-schema model”

A plugin is a candy (candy/<name>/charly.yml) carrying a plugin: block. The single addition that makes a candy a plugin is that block:

my-plugin:
candy:
version: 2026.180.1200 # mandatory CalVer (any candy)
description: |- # mandatory (ADE)
What this plugin provides.
plugin:
providers: [verb:myprobe] # "<class>:<word>" — class ∈ kind|verb|deploy|step|builder|command|build
source: builtin # OR github.com/org/repo/candy/<name> (out-of-tree)
primary:
myprobe: marker # scalar sugar target: `myprobe: hello` == {marker: hello}
plan:
- check: the myprobe verb dispatches and passes # ADE: ≥1 deterministic check
myprobe: { marker: hello } # the verb sugar — map value = the plugin input verbatim
context: [runtime]

A candy with no plugin: block is an ordinary candy; one WITH it is a plugin. Full candy authoring surface applies (/charly-image:layer), including the mandatory version:/description:/plan:+check: (ADE).

A plugin’s declarations are a PUBLISHED surface

Section titled “A plugin’s declarations are a PUBLISHED surface”

charly docs generate (see /charly-build:docs) renders one opencharly.ai page per plugin candy from three things this file already requires: the plugin.providers list, the per-plugin schema/*.cue, and the candy description:. Two consequences:

  • An empty, stale or placeholder description: is a public-docs defect, not just an ADE gate miss — it is the prose a reader gets for that plugin.
  • Placement is computed, never transcribed: the page states compiled-in vs runtime by reading charly/charly.yml’s compiled_plugins:, so moving a plugin between placements updates its documentation automatically. Never write the placement into the description prose; it will drift the moment the list changes.

The same three declarations are how an OUT-OF-TREE plugin documents itself — the generator cannot reach a repo it does not have, so its author publishes from the identical surface.

Topic File
The kernel/plugin boundary law (E/M/B/D/R, the decision procedure, the incomplete-seam self-test, the host-boundary-object trap, the resolve-to-envelope canonical shape) — sole owner of this doctrine — plus the v2 target architecture end-state references/boundary-law.md
The unified Provider model (transport-invisible dispatch, the build class, lifecycle phases, flat vs structural kind decode), placement (builtin/external × in-proc/out-of-process at build and deploy time), and the four authoring recipes (external, compiled-in, host-coupled kit, external command) references/authoring-recipes.md
The per-plugin CUE schema contract (dev-time Go params, runtime schema-over-Describe RPC), the load gate + validator, and why plugin schemas are self-contained references/cue-schema-contract.md
  • go test ./... — the registry/transport/schema seams (TestPluginGRPCRoundTrip, TestExternalPluginEndToEnd proves the schema travels over RPC, TestPluginSchemaSpliceValidation, TestBuiltinPluginSchemasSplice is the CI gate that every builtin schema splices).
  • task cue:gen — regenerates spec + every plugin’s params; reproducible (a second run is a no-op).
  • charly box validate — the candy + plugin: block (candy/plugin-box/validate_rules.go’s IsPlugin check — an explicit, documented 1:1 port of the former core validatePluginCandy, deleted as dead code in the 2026-07-22 dead-code-radical-removal batch once its call site moved here — verifies each capability is well-formed and, for source: builtin, that the provider is actually compiled in).
  • R10: a disposable bed composing a builtin AND an external plugin, driven to a fresh charly update — the builtin’s baked check + the external’s out-of-process check both pass.

Invoke before authoring or editing any plugin: block, any sdk/** code, the plugin SDK, a compiled-in plugin candy (compiled_plugins:) or host-coupled kit candy, an external plugin module, or the plugin schema/param gen pipeline.