Skip to content

config_schema is now required for every plugin that requests config_read (all 31 packages) #147

Description

@JordanTheJet

What is changing

ZeroClaw is adding typed, schema-validated plugin config (host PR zeroclaw-labs/zeroclaw#9126). Once it lands, a manifest that requests config_read without declaring config_schema is no longer discovered or installed. The two are a biconditional: declaring a schema without requesting the permission is equally invalid.

This ships without a compatibility shim or grace period. Plugins are a pre-1.0 experimental surface, and an untyped fallback would have to hand a guest values the host cannot type, name, or bound, which is the hole the feature closes. Packages that do not migrate stop being discovered; nothing is silently downgraded.

Every package in this repository requests config_read and none declares config_schema today, so all 31 need migration.

Why the host needs the schema

Operator values are stored as a secret-marked string map, encrypted at rest, and the guest is untrusted code. Before starting a guest the host must know which keys the package may receive and what type each value is. The WIT worlds are fixed and shared across all plugins, so per-package config types cannot live in the ABI. The manifest is the only place the contract can be declared, and additionalProperties = false plus an explicit properties map is what makes the config_read grant enumerable.

What each package needs

Full recipe with examples, limits, and error messages: Migrating to typed plugin config.

Short version, per package:

  1. Add a closed Draft 2020-12 [config_schema] to manifest.toml covering exactly the keys the plugin reads. Root must be type = "object" with additionalProperties = false; every top-level property needs one explicit type from string, boolean, integer, number, array, object.
  2. Mark credentials required so a withheld grant fails closed instead of starting half-configured. Optional keys receive {} when the grant is withheld, so give them guest-side defaults.
  3. Update the guest to deserialize the injected typed JSON once instead of parsing strings. Booleans, numbers, arrays, and objects arrive as real JSON values.
  4. Rebuild the component.
  5. Re-sign, if the package is signed: config_schema is covered by the manifest signature.
permissions = ["config_read"]

[config_schema]
"$schema" = "https://json-schema.org/draft/2020-12/schema"
type = "object"
required = ["bot_token"]
additionalProperties = false

[config_schema.properties.bot_token]
type = "string"
minLength = 1

[config_schema.properties.poll_interval_secs]
type = "integer"
minimum = 1

Schema limits enforced by the host: 64 KiB serialized, at most 32 levels of nesting, no $id, and $ref must be a local JSON Pointer. Remote references are rejected, so a schema never triggers a network fetch.

Operator-facing change in the same release

[[plugins.entries]] is now keyed by a full-instance key derived from package, capability, and binding (zpi1_...) rather than the package or binding name. Legacy entries are not consulted. zeroclaw plugin info <package> prints the key; fresh installs seed and print it automatically. Worth a line in each package's README where it documents configuration.

Checklist

  • amqp
  • bluesky
  • dingtalk
  • discord
  • email
  • gitea
  • gmail_push
  • irc
  • lark
  • line
  • linq
  • matrix
  • mattermost
  • mochat
  • mqtt
  • nextcloud
  • nostr
  • notion
  • qq
  • redact-text
  • reddit
  • slack
  • telegram
  • twitch
  • twitter
  • wati
  • webhook
  • wechat
  • wecom
  • wecom-ws
  • whatsapp

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationenhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions