RFX packs
RFX is the declarative capability format. A reflex is a pre-wired capability, a pack is a folder of them, and RFX_UI lets a pack put its own control panel in the chat without shipping any code.
rfx: 1 keeps working under v1 semantics forever. Breaking changes ship as rfx: 2, never as a silent edit to what v1 means.
Vocabulary
Packs
A folder inside ~/.crv/rfx/ is a pack if and only if it contains a valid pack.yaml:
rfx: 1
pack: swarm-tools
version: 1.2.0
author: you
description: Camera fleet helpers
- One folder level. No nesting.
- Reflex names stay global. A pack is organisation, not namespacing — a cross-pack name collision is a rejection like any other.
- A folder without
pack.yamlis ignored with a loud notice, never silently. A pack that does not load and does not say so is worse than one that fails. docs/*.mdinside a pack are discovered and listed.
Capability cards
Every reflex carries a permission manifest: filesystem scope, network allowlist, environment visibility, subprocess rights. Checked in Go at install and again at every dispatch — the guard reads the calling tool's card rather than trusting the pack.
Fuzz contracts
crvcli rfx test generates argument sets from the parameter schema, dry-runs them, and verifies output conformance, timing and cap behaviour. A misbehaving reflex is refused before it ever registers. Failure is a siren, never silent.
The recipe executor
A reflex runs by re-dispatching each step through the tool registry itself, so the guard, the remediator, ingress caps and episodic logging all apply per step for free — rather than being re-implemented, or forgotten.
Typed parameters are validated against the generated GBNF: no string templating, and therefore no shell-injection surface. An alias is just a one-step recipe.
Reflex kinds
A reflex's tool calls go through the same registry, the same guard and the same mode fencing as anything else. Mode fencing propagates through a reflex: a bash step inside one is still autopilot-only. See The three modes.
rfx_loaded / rfx_rejected notes land in the episodic log. Registering a capability the model was never told about was a real gap, and closing it was the fix.
State lives outside the manifest
~/.crv/rfx/.state.json holds the enable/disable toggles:
{ "disabled": ["noisy-reflex"] }
User content is never edited to change state — disabling a reflex does not touch the file you wrote. A disabled reflex is still valid; it simply leaves the grammar on the next turn.
crvcli rfx list
crvcli rfx show <name>
crvcli rfx install <path>
crvcli rfx remove <name>
crvcli rfx test <name>
All local — no running server needed. The panel exposes the same toggles under Settings → RFX Talents.
RFX_UI
A pack may declare a ui: block in pack.yaml: a declarative widget list rendered as the pack's cockpit card in the chat dock. Available widgets:
No code, no HTML — the panel owns the pixels. That is what makes a pack safe to install: a declarative widget list cannot execute anything the registry did not already allow.
Full custom panels
A pack that needs more than widgets can ship a full panel, served into a sandboxed iframe behind an rfx bridge. It talks to the core only through that bridge, never directly. Served by GET /api/rfx/panel/{pack}.
Two actors, one surface
Cards live in the chat's right-hand dock and refresh from the episodic stream. When the model runs a reflex its card updates live; when the human clicks a quick-run button, that run lands in the same log the model reads.
Buttons invoke through the registry with their preset arguments — same guard, same caps, same logging as a model-issued call. Manual execution is a first-class path: you can fire reflexes the model never asked for, and it will see that you did.
exec reflex has the same reach as bash. Install packs you wrote or read.
Routes
Guidebook auto-fixes
The registry keeps a book of self-fixes. A mechanical failure — a busy port, an invalid regex — is repaired and retried by the registry itself rather than handed back to the model as an error it has to reason about. The repair is disclosed as [auto-fixed] in the tool card, because a silent correction is indistinguishable from the tool having worked first time.