Advanced runtime blocks
This is an extension-author and operator reference. Personal onboarding chooses recommended runtime defaults and does not expose these registries.
Everything in moxxy resolves through a registry. Fifteen kinds, each with a protected floor a plugin can add to but never shadow.
moxxy plugins defaults # what each kind resolved to
moxxy plugins use <kind> <name> # change oneUse moxxy onboard --advanced when you deliberately want runtime and channel configuration. Default moxxy onboard only connects a model account.
The kinds
| Kind | Decides | Floor | Also ships |
|---|---|---|---|
provider | which model answers | anthropic | openai, openai-codex, claude-code, google, xai, zai, local, plus any OpenAI-compatible endpoint |
mode | the shape of the loop | default | goal, research, collaborative |
compactor | what happens to old turns | summarize-old-turns | bring your own |
cacheStrategy | where cache breakpoints land | stable-prefix | none |
isolator | the boundary a tool runs inside | — (off) | none, inproc, worker, subprocess, wasm |
eventStore | where the log is written | jsonl | bring your own |
auditSink | where the receipt goes | local | bring your own |
reflector | what carries between turns | default | bring your own |
transcriber | speech in | — | whisper, whisper-codex, local |
synthesizer | speech out | — | openai, elevenlabs, local |
embedder | how memory is vectorised | tfidf | openai, transformers |
workflowExecutor | how a DAG is walked | built-in | bring your own |
viewRenderer | how an authored view is drawn | built-in | bring your own |
tunnelProvider | how a listener gets a public URL | proxy | bring your own |
channel | the surface driving a session | tui | ten more |
A dash in the floor column means the kind has no default registration. Nothing is registered for transcriber until you install one, which is why onboarding drops the category entirely rather than showing "(none)" and inviting a question you cannot act on yet.
What "protected floor" buys you
Registering is not activating.
- A discovered plugin adds its implementation to the registry.
- It cannot replace the floor.
- Making it active is always an explicit
setActive, a command, or a config key. - Removing a non-floor entry reverts to the floor, never to nothing.
The consequence worth stating plainly: installing a plugin is safe to try. The worst case is an agent that ignores it, not one whose spine changed underneath you.
auditSink takes this one step further. A discovered sink is registered but never auto-activated even if it is the only one, because a sink's whole purpose is to send recorded actions elsewhere and silent adoption would be an exfiltration path.
Changing one
Most kinds are a command:
moxxy plugins use provider openai
moxxy plugins use mode goal
moxxy plugins use embedder openaiisolator and channel are persist-only — their active value is not a live session slot — so they apply on the next boot and are set in config:
plugins:
isolator:
default: subprocessAnd a few carry their own configuration block:
audit:
enabled: true
sink: siemUnder policy
Any of these can be pinned by an operator so a user cannot change it:
plugins:
isolator:
default: subprocess
locked:
- plugins.isolatorWriting one
Each kind has a define* factory in @moxxy/sdk, and a plugin contributes an array of them:
import { defineCompactor, definePlugin } from '@moxxy/sdk';
export const dropOldest = defineCompactor({
name: 'drop-oldest',
async compact(ctx) { /* … */ },
});
export default definePlugin({
name: '@acme/compactor-drop-oldest',
version: '1.0.0',
compactors: [dropOldest],
});See authoring a plugin for discovery, requirements and packaging.
Next
- Loop strategies
- Surfaces and channels
- Architecture — why the registries are shaped this way