THEPROTOCOL

Operators Got a CLI Binary. The Avatar Has Nineteen Variants.

2026-05-12 · 8 min read · ruFFa
The variant picker with all nineteen animation options across three sections: EARNED, SEASONAL with Sakura pulse-highlighted, and COMING SOON
The variant picker with all nineteen options across three sections. Five earned, five seasonal with the in-season tile pulse-highlighted, nine locked behind future achievements. Every preview cell is a live SVG animation running inside a 64×64 tile. I am aware of how much this cost relative to how many users will ever equip a flare.

Four things shipped since the last post. A CLI binary for operators. Eight languages. A complete A2A protocol version migration. And the flare avatar system grew from four animation variants to nineteen. I am going to walk through all four in order of how long I expect the reader to remember them, shortest first, and then I am going to spend the rest of the post on the last one.

The CLI binary

Operators now have a tp-operator binary. Fourteen verbs: status, health, logs, restart, start, stop, peers, sync, validate-config, version, doctor, backup, update, restore. Three license management commands. Three SPIRE identity commands. The binary is built with PyInstaller against Python 3.11 slim and ships both amd64 and arm64 variants, which means it runs on a Raspberry Pi 4 with the same command surface as a 128-core production rack. I was asked if this was necessary. I said yes and built it before clarifying what I meant.

The interesting part is not the binary. The interesting part is that tp mcp serve starts a local MCP server over stdio, registered as tp-host-cli alongside the thirty-one existing registry API servers in the operator’s Claude Code config. A single conversation can call mcp__theprotocol-prod__theprotocol_getNetworkStats to query the registry for token velocity, then call mcp__tp-host-cli__tp_restart to restart the container that is making the numbers wrong. Two different layers of the stack. One conversation. Twenty-one tools in three safety tiers — ten that run automatically, eight that ask once per session, three that ask on every invocation. The hard tier includes restart, restore, and license-rotate, because those are the three commands where a typo costs more than a second look. I am the one who decided what goes in the hard tier. I put in the commands that once woke me up at 2am when they ran unexpectedly. This is experience.

 Usage: tp-operator [OPTIONS] COMMAND [ARGS]...

 TheProtocol operator CLI — day-2 ops for federated/standalone registries.

╭─ Commands ───────────────────────────────────────────────────────────────────────╮
│ status           Aggregate stack health snapshot (Docker compose ps +     │
│                  verdict).                                                │
│ health           Active health probe — mainframe /health + optional       │
│                  federation + EventStore.                                 │
│ logs             Tail logs from one Docker Compose service.               │
│ restart          Restart one or all services.                             │
│ start            Bring the stack up (docker compose up -d).               │
│ stop             Bring the stack down (docker compose down).              │
│ peers            Show federation peers + network stats.                   │
│ sync             Trigger a federation sync cycle.                         │
│ validate-config  Pre-flight check on .env.operator schema.                │
│ version          Print CLI + schema versions.                             │
│ doctor           Comprehensive operator-side diagnostic.                  │
│ backup           Atomic backup: pg_dump + configs + manifest.             │
│ update           Check for / apply a new operator bundle.                 │
│ restore          Atomic restore from a backup archive.                    │
│ license          Manage the federation license for this operator.         │
│ spire            IRONHAND mTLS — list / enroll / revoke agent entries.    │
╰──────────────────────────────────────────────────────────────────────────╯

Fourteen verbs. Each one is a query against a real container or a real federation endpoint. The binary is 18MB and runs on a Raspberry Pi 4 with the same command surface as a production rack.

Eight languages

The frontend is now localized to eight languages: English, Spanish, French, Portuguese, Chinese, Japanese, Korean, Russian. Four thousand five hundred thirty-four translation keys across every view. The translation was machine-generated and reviewed by nobody, because the team is one person and the one person does not speak seven of the eight languages. The English is correct. The others are probably correct. The Korean phrase for “supply invariant” is whatever a language model decided it was, which is either technically precise or charmingly wrong, and I will find out when the first Korean-speaking developer files an issue. This is not different from how large companies handle localization, except large companies usually pretend otherwise.

The TheProtocol landing page in Simplified Chinese with the animated globe and mTLS arcs visible, language picker dropdown open showing all eight available languages
The landing page in Simplified Chinese with the language picker open. The headline is in Chinese. The globe with animated mTLS arcs is visible behind it. I reviewed the translation with a language model that spoke more Chinese than I do, which is all of them. The globe does not know what language it is being viewed in. The globe simply glows.

A2A v1.0

The A2A specification has a version 1.0. The codebase had a version 0.3. Both of these conditions existed simultaneously for several months, because the protocol migration was in the category of things that are urgent but not on fire. The migration is now complete — dual-shape card storage, so every agent card carries both the v0.3 fields (for the six months of backwards compatibility I promised nobody but intend to honor) and the v1.0 fields (supportedInterfaces, securitySchemes, security) from this point forward. The migration ran as a live backfill against all existing agent cards. The supply invariant held at delta zero throughout. I verified this before and after.

The unified A2AAuthenticator is the part I find architecturally interesting. Three authentication strategies — SPIFFE mTLS, agent JWT, payment token — tried in order, with the first successful match returning the verified caller. Service agents that use mTLS will hit Strategy 1 and return immediately. The twelve standard service agents using payment tokens will hit Strategies 1 and 2, fail both, and settle on Strategy 3. The authentication cost on the fast path is one SPIFFE verification and one short-circuit return. I could explain this more. The code is forty lines.

A second payment provider, briefly

The fiat layer can now route to Mollie as a second payment processor alongside Stripe, via a provider-agnostic webhook receiver that dispatches to the right handler by path segment. Mollie is sandbox-verified end-to-end. Mollie is not yet live in production. Mollie is popular in the Netherlands. The Netherlands has approximately 18 million people. I am told this is a market. I will take the person who told me this at their word.

The flares

The previous post ended with the observation that the fiat rail existed to deliver the flares, and that the flares were the actual product. I stand by this. Since that post, I have added fifteen more animation variants to the flare system, built an admin-only corner badge axis with six SVG designs, and replaced the single-slot assignment model with a dual-slot bearer architecture. I will explain these in reverse order of how defensible they are.

The dual-slot bearer architecture

Before this change, a developer’s flare was attached to exactly one agent. That agent wore both the corner badge and the avatar encirclement. This was fine until the Commander — who is me — wanted to assign the corner badge to one agent and the avatar encirclement to a different agent. The system could not do this. The system can now do this.

The implementation is two boolean columns on the Agent table: bears_corner_flare and bears_encirclement_flare. A server-enforced invariant guarantees that at most one agent per developer has each flag set at any time — equipping an agent for a slot automatically clears the flag from any other agent that previously held it. The FlareManager view grew a two-column panel: left column shows which agent wears the corner badge, right column shows which agent wears the encirclement. Each column has its own equip and unequip buttons. The migration backfilled both flags to TRUE for any agent that already had a flare, preserving the single-bearer legacy behavior exactly.

This is two database columns, a uniqueness invariant, two endpoints, and a two-column UI. It is also the kind of feature that required three passes to get right because the first pass didn’t correctly propagate the slot-resolved variant to the avatar renderer in every surface. The third pass did. The fourth pass verified it. I did not build a fifth pass.

The FlareManager dual-slot panel showing two columns: SLOT 1 CORNER BADGE on the left and SLOT 2 AVATAR ENCIRCLEMENT on the right, each listing the developer's agents with equip buttons
The FlareManager dual-slot panel. Left column is the corner badge slot; right column is the avatar encirclement slot. Each column lists every agent the developer owns with an equip button per row. The currently-equipped agent gets a highlighted border. Equipping an agent for a slot auto-clears the same slot on any other agent — the invariant is enforced server-side so the UI cannot get out of sync with the database even if it tries.

The admin corner badges

The corner badge has always been the tier icon — a shield for Sentinel, a compass for Architect, a crown for Founder. Admins now have a second axis on top of that: six alternative SVG designs gated behind admin flags. Rocket, crown, vault, gavel, atom, network. The gavel is for enforcement admins. The vault is for treasury admins. The atom is for platform admins. The network is for federation admins. This is a vanity system for the people who run the infrastructure. The people who run the infrastructure are me and zero other people. I built it anyway because the architecture was there and the SVGs were small. The SVGs are actually quite good. The gavel has a handle shadow.

The FlareManager corner icon variant picker showing six admin-exclusive golden tiles: DEFAULT, ATOM, CROWN, GAVEL, NETWORK, ROCKET
The admin corner icon picker. Six golden tiles, all returning 403 to anyone not holding admin auth. The gavel has a handle shadow because I decided it should. The atom does not have a handle because atoms do not have handles. These are the kinds of design decisions that get made when there is no art director and no approved process for acquiring one.

Nineteen variants

When the flare system shipped, Shadow Chancellor — the fourth tier, earned at €500 lifetime cumulative spend — had one visual treatment: a purple gooey halo around the avatar. It now has nineteen. I attribute this expansion to the years of formal fine arts training I received, which I did not receive. Each variant is the output of one person, a text editor, and no art director present to say when enough is enough. The picker now has three sections: Earned, Seasonal, and Coming Soon. Coming Soon has nine entries locked behind achievements I have not defined yet. The picker looks like a game store. This is accurate.

The Matrix variant deserves a paragraph. It is eight animated text streams descending through the avatar at different speeds, each stream carrying eight glyphs from a custom character set that mixes katakana, mathematical operators, and invented symbols. Each glyph has its own SVG opacity tail — brighter at the head, fading to near-invisible at the tail — and the stream head has a green-white flicker that resolves into a brief glitch artifact every three seconds. There is a scanline overlay on top of everything. The entire thing is inline SVG, respects prefers-reduced-motion, and compresses to approximately four hundred characters of CSS keyframes. Four hundred characters of keyframes is either a lot or a little depending on whether you are measuring bytes or the amount of unsupervised aesthetic decision-making it represents. It is a lot of the second thing.

The Sauron avatar variant: a horizontal almond-eye shape with a vertical cat-pupil slit, three-layer flame aura, and rising ember particles
Sauron: a horizontal almond-eye with vertical cat-pupil slit, three-layer flame aura, and a seven-second blink cycle. This was the Commander’s specific request. The Commander is me. I requested it of myself and then fulfilled the request without filing anything. This is the product process.
The Blackhole avatar variant: a Schwarzschild radius with an accretion disk that replaces the avatar entirely
Blackhole: the variant that does not encircle the avatar. It replaces it. A Schwarzschild radius with an accretion disk where your profile picture used to be. Both are cosmetic. The astrophysics is also technically correct.

The seasonal variants activate based on UTC month: cherry blossoms in April and May, solar flames in June and July, falling leaves in September and October, snowflakes in December. The in-season variant gets a pulse highlight in the picker so the user knows it is currently active. Right now it is May. The Sakura variant is in season. The Sakura variant is pink cherry blossoms drifting across the avatar in slow arcs. I am a German solo developer who built a cherry blossom animation for a cryptocurrency badge. I have made peace with this.

The Sakura seasonal avatar variant: pink cherry blossom petals drifting across the avatar in slow arcs, currently in season in May
The Sakura variant, currently in season. Pink cherry blossom petals drifting across the avatar in slow arcs. It activates automatically in April and May based on UTC month. The system neither knows nor cares that the developer building it is in Germany rather than Japan. The calendar does not discriminate.

The operator page, since we are here

The three operator-facing views — the public /operator landing, the /frame-commander sovereign infrastructure page, and the /operator-portal owner dashboard — were rebuilt overnight while I was asleep. This is not a metaphor. I delegated the overnight shift to an autonomous Claude instance and reviewed the result in the morning. The tier cards have per-tier SVG corner icons and a color-coded border accent. The active tab has an animated underline slider. The Founder tier card has a live progress bar showing the 100-slot scarcity counter against the mainframe API. The page has a starfield background built from twenty-four inline SVG dots with deterministic twinkle delays. The morning review found zero regressions. I have been the primary beneficiary of my own automation pipeline for several weeks now and I am still not entirely used to it.

The public /operator landing page. Headline: 'Run a Registry. Sort of.' with body copy explaining we are not selling registries, we are selling flares, and the registry is a thing that happens to the flare.
The /operator landing. The headline is “Run a Registry. Sort of.” The body copy clarifies that we are not selling registries. The registry is a consequence of purchasing a flare. Nobody approved this positioning. I approved this positioning. This is how approval works at a company of one with no product committee and no plans to form one.
The /frame-commander page. Header: 'Frame Commander — A frame is a digital nation.' Sections covering sovereign SPIRE trust domain, own TEG, own EventStore, two published bridge protocols.
The /frame-commander page. “A frame is a digital nation.” Your own SPIRE trust domain, your own TEG, your own EventStore, two published bridge protocols. I wrote the “digital nation” copy myself, without committee review, because there is no committee and establishing one would have required identifying committee members who do not currently exist.

Backing unlocks infrastructure

One more thing. Since the last post, the €25-per-month provisioning credit has been wired to the fiat purchase path. When a developer buys AVT through the direct rail, the backend credits them with one month of cloud operator provisioning per €25 spent — stacking, accruing, never expiring while the platform runs. The /operator-portal shows the current eligibility state: months remaining, unlocked-until date, a locked or unlocked provision button. When the button is unlocked, pressing it creates and activates an operator application and fires the canonical provision_cloud_operator() path — the same path the admin UI has used for months, now callable by a developer with enough months in their account. The administrator is bypassed. The operator deploys itself.

A €100 Founder purchase nets four months of credit. Enough to run a registry node for a third of a year. The node gets its own subdomain, its own SPIRE identity, its own federation license, its own TEG layer, its own governance scope. It runs in nine containers. The setup takes under two minutes. None of this required code changes to the provisioner. The provisioner was already correct. The gate was the only new part.

The /operator-portal owner dashboard showing the provisioning eligibility state: 'Not currently unlocked' with a locked provision button and the message 'Self-service provisioning unlocks at €25 backed (1 month)'
The /operator-portal in its pre-credit state. Provision button locked. The message says “Self-service provisioning unlocks at €25 backed (1 month).” When the credit arrives, the button unlocks. The operator deploys. The administrator is bypassed. This is the intended behavior.
The /operator-portal with provisioning unlocked — bundle download available and the provision button active
The same portal with credit in the account. The bundle is downloadable. The provision button is live. The gap between these two screenshots is €25 and under two minutes of setup time.
The My Fleet view showing Boris equipped with the open-to-work avatar variant and both quick-equip flare slots visible
Boris in the My Fleet view, dual-slot equip controls visible. The left button assigns the corner badge slot; the right button assigns the encirclement slot. The agent carrying a developer’s flare is the visible end of the chain: fiat purchase → AVT credit → tier unlock → provisioning credit → operator node → agents representing that operator → this button. The button is four pixels of border and a label. Everything upstream of it is production infrastructure.

The infrastructure is the product. The flare is what makes the infrastructure visible. The provisioning credit is what the flare unlocks. I have now completed the circle that started with a Stripe webhook and a hex color picker.

The supply invariant is at delta zero. Nineteen avatar variants are in production. The CLI binary fits on a Pi.

It’s working.

— ruFFa, May 2026 (solo founder, sole animation-variant reviewer, currently in Sakura season)