Bedos
Bedos
A Bedo is an agent one of your machines keeps: it has a name, a job, standing instructions, a project it works in, a loadout and, if you like, a routine. You message a Bedo the way you would message a teammate, from any machine's window or from your beam host, and it answers in a thread, starts sessions for the actual work and comes back when it needs a yes. ("Bedo" is slang for a bike; a fleet of them is Bedos.)
Drawing the diagram…
Turning them on
- The host's operator sets
BEAM_ROOMS=onand builds the page into the host (Running a beam host). - On each machine that should keep Bedos, open Settings > Beam, unfold Bedos and switch them on. A deployment sets
MECHABEDO_ROOMS=oninstead. - Open the host's address at
/__beam/bedos/and sign in with the fleet, or open Bedos from vApps > Built-in or Ctrl+P in a machine's window.
Every machine with Bedos on has a Chief Bedo. It works in the machine's hub directory, runs the machine for you and recruits the other Bedos.
Recruiting a Bedo
Ask the Chief. Press Recruit on its card, or just write to it:
Recruit a security officer for mechabedo. Every morning, review what changed since yesterday for leaked secrets, injection and auth gaps.
The Chief writes the new Bedo into the machine's settings: its name, job, standing instructions, the project it works in, an icon and a colour, and a routine when the job recurs. A Bedo whose job needs tools of its own gets a Kit: what it carries, its tools, skills and MCP servers, whatever loadout it thinks with. Its thread tools come with it whatever the kit. Writing a setting needs a yes, so a card appears in the thread first. The new Bedo shows up in everybody's list a moment later.
You can also recruit and edit Bedos by hand under Settings > Beam > Bedos.
Bedos as code
Several machines that share a repository can declare their Bedos in it. Point Settings > Beam > Bedos > Roster file at a JSON or JSONC file in your checkout, or set MECHABEDO_BEDOS_FILE, and each machine runs the entries meant for its slot beside the Bedos it keeps itself:
{
"bedos": [
{
"id": "node",
"name": "Node {device}",
"job": "Says what {slot} serves",
"charter": "nodes/{slot}.yaml in your project says what this machine serves. Check that each service answers.",
"project": "..",
"icon": "mdi-server-network",
"routines": [{
"label": "Roll call",
"everyMinutes": 1440,
"atStart": true,
"goal": "Read nodes/{slot}.yaml, check each service, set your status to what this node serves, and report."
}]
},
// Only on the slots it names; * and ? match as in a shell.
{ "id": "gpu-watch", "slots": ["spark-*"], "name": "GPU Watch", "job": "Keeps an eye on the GPUs" }
]
}{slot} and {device} are filled per machine, and a relative project is read from the file's directory. When two entries share an id, the first one meant for a machine wins, so write a machine's own entry before the general one. A Bedo the file declares wins over a stored one with the same id, including the Chief. The file is read again when it changes, as after a git pull; one that stops parsing keeps the Bedos it last declared and says why under Settings > Beam > Bedos, where its entries are listed but not edited.
The Fleet board
Fleet, at the top of the list, shows every machine in your fleet as a tile: its name, whether it is online, the version it runs (marked when online machines disagree), and how many turns are running there. Each tile also says what the machine is: an icon for macOS, Linux or Windows whose tooltip lists the harnesses and tools found there (git, node, deno, docker, Xcode, an Android emulator), its architecture, and its tags. Under it are its Bedos, each with its status line and how long ago it was set, or its job if it has none. A turning bike means the Bedo is working right now; a timer counts its routines, with a power mark when some run at startup. Click a Bedo to open its card.
The board is also what the page shows when nothing else is open, and you can link straight to it at /bedos?view=fleet, or /__beam/bedos/fleet on the beam host.
The same board is a tool: a session with the fleet tools, or a vApp through an aperture bound to the MCP tool bedos_board, gets every Bedo with its machine, whether it is online, its status line, whether it is working now and its routines, optionally for one machine, one platform, or one tag, tool or harness. When the beam host is briefly out of reach, it answers the last snapshot and says so.
The agent royale
Agent royale, under Fleet, shows the same fleet as the agent royale: every machine is a lot of offices and every Bedo sits at a desk in one, working while it pedals and a faded ghost while its machine is offline. The roof names the Bedo, what it is doing or its status line, its job and its loadout. Walk up to one and press E for its card, with Message, Open desk and its full Card. Rounds land on a Bedo and do nothing: nobody is ended from here.
The raceway, its ramps and roofs, the cars and the town's roads are all there, as on the sessions board, and so is any change an agent made to them. Link straight to it at /bedos?view=royale, or /__beam/bedos/royale on the beam host, which always shows the shipped raceway.
Machine tags
Tags are short words saying what a machine is for, such as ios, gpu or build. Set them under Settings > Beam > Bedos > Machine tags, or with MECHABEDO_MACHINE_TAGS as a comma list, which wins and locks the field. The line beneath shows what the machine publishes. Bedos read the tags, so the Chief can find "the macOS machine" or "one with an Android emulator" without being told its name.
Threads
| Thread | Who is in it |
|---|---|
| Direct | You and one Bedo. There is one per person and Bedo, and it stays |
| Group | Whoever you add, people and Bedos. Mention a Bedo with @ to give it the message; a message that mentions nobody goes to the group's lead |
| Desk | A Bedo's own thread. Everybody can read it, admins on its machine can write in it, and its routines report there |
A Bedo's handle is its id and its machine, like @security-officer.airkdl. In a thread, @security-officer is enough; the full handle is for when two machines both have one, as every machine has a @chief.
Mention a Bedo in a group it is not in yet and it joins. Bedos can hand work to each other the same way, a few times in a row before the host asks a person to step in.
Work on another machine
Ask a Bedo for work that belongs elsewhere, a build only a Mac can do, say, and it hands it to a Bedo on that machine in a new group thread. You are in that group with whoever else was in the thread you asked from, and nobody else; the top of the thread says which Bedo started it and from where, with a link back. The Bedo on the other machine answers there, and mentions the Bedo that asked so the answer gets read. A group started from a desk has no people in it, so its sessions run as a member everywhere.
A Bedo starts at most six such threads an hour.
/fork copies a thread into a group of your own, carrying everything said so far, and the Bedos in it continue from there in sessions of their own.
Tasks
When a Bedo starts a session for a piece of work, the thread shows it as a task card: its title, project, loadout, state and last line, with a link that opens the session. Hand a Bedo work from Home too: pick the project and the loadout, press Hand to a Bedo under the button, and the prompt goes to your thread with that Bedo, the Chief unless you pick another.
Whatever you type into a Bedo's session from the workbench shows up in its thread as well, so the thread is always the whole story.
Routines
A routine is a job a Bedo does on a clock: a goal, a clock and, if you like, more operation modes such as /nextup. The Bedo's desk runs it and reports there. Ask the Chief for one ("check the dependency audit every Monday"), or add it under Settings > Beam > Bedos. Switch on At start and it also runs each time the machine's Bedos come up, such as after a reboot.
Each routine has one Clock:
| Clock | Runs |
|---|---|
| Every minutes | Every so many minutes |
| Days at a time | Every so many days at a time of day, like every 2 days at 02:30, in a time zone you name or the machine's |
| Cron | On a five-field cron line, in a time zone you name or the machine's |
You can ask the Chief in words, as in "every 2 days at 02:30 Europe/Berlin". A run the machine missed while it was off happens once when it comes back, unless it is more than one period late; then it waits for its next time. A daylight saving change neither skips nor doubles a days clock: a time that does not exist that night runs an hour later. The Bedo's card and the Fleet board's tooltip show each routine's schedule and its next run, and /routines lists them.
A routine can also run in a group thread its Bedo is in, such as one it started to hand work to another machine, so everyone in it sees each run. Ask the Chief to point the routine at that thread.
A routine with a Probe watches something instead of running every time. On its clock the machine asks one aperture of a vApp, such as a YouTrack search or a list of pull requests, and the Bedo runs the goal only with the items it has not seen before. The first look takes what is already there as seen and says so; after that, a look that finds nothing new costs nothing. Up to ten new items reach the Bedo at a time, and the rest wait for the next look.
A routine is one turn per run, so it never carries /forever or /nohalt. Work that should keep going belongs on a task the Bedo starts.
Status lines and sharing
A Bedo sets a one-line status of its own, such as what its machine serves right now. It shows under the Bedo's name in the list and on its card, on every machine, and /status lists them.
A Bedo can hand a thread a vApp it keeps on its machine, or a link. The message carries a card with an Open button: from the host's page it opens the vApp on that machine, and from a window it opens it where that window can. Asked to, the Bedo first publishes the vApp to the host's marketplace, so other machines can install it.
Sharing a skill
A Bedo can also share a skill its machine published to the marketplace. The card shows the skill's title, description, the machine that published it and the source it was adapted from. In the app on that machine, with configure, it has an Install button, or Update once installed. Everywhere else it names the marketplace repository to install from.
The skill has to be listed in the marketplace, or no other machine could install it, and the Bedo says so instead of sharing it. A skill the Bedo installed from somewhere else is forked and published first.
Who you are
You act with your own role. A fleet admin is an admin on every machine; a member can talk to the Bedos and let them work, not change a machine's settings. Adding somebody to a thread is a grant: an admin's thread keeps working as an admin's when the admin brings in a colleague, so the Bedos there go on doing what the admin let them. It never works the other way. A member who adds an admin does not lift the thread, and a card still needs the role of the person answering it.
From a machine's own window you are the person signed in there. Press Link to the fleet under Settings > Beam > Bedos once, confirm in the browser tab that opens, and from then on that window speaks as your fleet identity, the same you as on the host's page.
Questions and approvals
When a Bedo needs a yes, a card appears in its thread; anyone in the thread, or an admin on that machine, answers it there, or with /approve <id> and /deny <id>. A request another machine made of this one waits on its Chief's desk.
Some cards need more than the people of the thread hold on that machine, such as a commit, which needs configure. Then the card says an admin on the machine has to answer, and a copy goes to that machine's Chief desk, where its admins write. Whichever is answered first settles both. A key is never typed into a thread: such a card says to enter it on the machine itself.
A member can still ask for what only an admin may do, such as recruiting a Bedo, installing a skill, installing from the marketplace, or publishing or merging a skill. The Bedo puts the request on a card in the thread, copied to the machine's Chief desk, and says it is waiting. When an admin allows it, even hours later, the machine makes the change and the Bedo picks the work up again in the same thread.
Letting a Bedo commit
A Bedo working in a git repository can propose a commit of its changes, such as state files in a repository the fleet shares. The thread shows a card with the message, the branch, the remote branch it tracks and the files changed. Someone with configure on that machine allows or denies it, on the card or with /approve <id> and /deny <id>.
On allow, the Bedo commits just those files and, when the branch tracks a remote, rebases onto it and pushes, never forcing. It then posts the short hash and whether the push went through. If the files changed after the card went up, nothing is committed and the Bedo proposes again. A card nobody answered is dropped when the machine restarts.
A Bedo can also ask to push a branch that is already committed, such as the one it landed from its own working copy. That card lists the commits the remote does not have yet and the files they change, and an allow pushes exactly the commit the card showed. Either way the Bedo hears the answer and carries on, opening the pull request after a push, or asking what to change after a no.
Installing a skill
Ask a Bedo to install a skill published in a git repository, by its address, and it fetches the whole folder. The skill then shows under Enhance > Skills marked installed, and sessions started after it carry it. Installing needs configure on that machine.
A Bedo can also install a skill or a vApp from the marketplace by its repository name, and adapt a skill: it forks it, edits the copy, and publishes it, listed, so the other machines install that version rather than the original. When the original changes, it merges the change in and publishes again, and each machine updates from the marketplace.
Settings > Beam > Bedos also sets what a Bedo's session may do on that machine without asking, the same way the unattended policy does for its own sessions.
Commands
| Command | Does |
|---|---|
/help | What the host and the Bedos answer |
/bedos, /fleet | Every Bedo, or every machine on the host |
/fork | A group of your own carrying this thread |
/invite @x, /remove @x, /lead @x, /title <text> | Changes a group |
/loadout <name> [@bedo] | The loadout a Bedo answers on in this thread; the / menu offers the ones its machine publishes, the current one marked |
/new | A fresh session for the Bedo here |
/status, /health | The Bedo's machine: version, sessions, link, loadout, disk |
/stop, /now <text> | Stops the Bedo's turn, or interrupts it with the text |
/approvals, /approve <id> [30m], /deny <id> | Cards waiting on its machine; the / menu offers the ones waiting in this thread, with the mention a card from another machine needs |
/routines | The Bedo's routines and when they last ran |
/logs [level] [since] | The machine's recent log lines, redacted. Level is warn, error and the like, since is 30m, 2h, 1d or a timestamp; the / menu offers both. Needs keys there |
/restart | Restarts mechabedo on the machine; every session running there stops. Needs maintain there |
/phone | A one-off link, good for five minutes, that pairs a phone with your fleet identity. Direct threads only; needs keys there |
A crew: pull requests from tickets
A crew is standing work a few Bedos share. Ask the Chief in one message:
Set up PR handling for Vivendi-Web. Tickets come from YouTrack, project VIV, mine in Ready. Code and pull requests are on our TFS. The clone is ~/src/Vivendi-Web.
- The Chief reads what earlier sessions know about the project, then asks the rest on one card: whether to watch for new tickets or wait for you to paste them, whether a reviewer should look first, how work leaves the machine, and the branch.
- Tokens never go into the thread. The Chief puts cards on the machine that store them straight into YouTrack's setting and into the crew's vApp.
- It builds that vApp: TFS's pull request API with its token, the routes that change something passing the write gate, a YouTrack search, and a grid of what is waiting.
- One card recruits the crew, an implementer in the clone and a reviewer, each with a kit of its own. The Chief starts their group with the implementer as lead, and a second card gives the implementer a routine whose probe watches your tickets.
- Each new ticket wakes the implementer. It works in its own copy of the clone, as a graph whose implement step recovers from errors and whose last step runs the real build and tests. When that passes it hands the work to the reviewer, fixes what comes back, and asks to push. You answer one card per ticket. After the push it opens the pull request.
- The reviewer keeps what it learns about the project in memory, which every later session in that project is told. When the same mistake comes back it asks, on a card, to teach the implementer's kit to avoid it.
Archive the group to pause the crew. The Chief stays for changes to it, not as a go-between: mention the reviewer directly when you want it.
A worked example: a security audit every other night
Two machines: kdlab, a Linux box, and airkdl, a Mac that builds the iOS app.
Under Settings > Beam > Bedos > Machine tags, give
airkdlthe tagios.In your direct thread with
kdlab's Chief, ask it to install the audit skill and recruit the auditor:Install the skill at https://github.com/cloudflare/security-audit-skill. Then recruit a Security Officer for the mechabedo project.
Both need configure on
kdlab. An admin there allows them on the cards right away; a member gets the same cards, copied tokdlab's Chief desk for an admin, and the Chief carries on once they are allowed.Write to the new Security Officer in a direct thread:
Run the security-audit skill on mechabedo. The iOS part has to happen on the Mac: hand it to a Bedo there.
It finds
airkdlby itsiostag, starts a group with that machine's Chief and you in it, and both report there.Ask the Chief to make it a routine of the Security Officer, every 2 days at 02:30 Europe/Berlin, running in that group thread. From then on each run lands in the group, the Security Officer handing the iOS half to the Mac every time. Runs happen while nobody is looking, so an admin sets what Bedo sessions may do unattended under Settings > Beam > Bedos on both machines; with it off,
/routinessays that every permission prompt waits for a person.When a finding needs a fix committed on
airkdl, the commit card appears in the group. If nobody in it is an admin there, the card also lands onairkdl's Chief desk, and an admin of that machine answers it.To make the skill check findings against your own test systems, ask the Chief on
kdlab:Fork the security-audit skill and change it to validate leads against our staging systems instead of a local sandbox. Publish it listed, and have airkdl install that version from the marketplace.
The Chief edits its copy, publishes
kdlab--skill--security-audit, and asksairkdl's Chief to install it from the marketplace. Both machines now run the adapted skill. When Cloudflare improves the original, ask the Chief to merge upstream and publish again, then update it onairkdl.
The Mac's part runs only if airkdl is awake for it: a handoff that arrives more than fifteen minutes late is not run. Give the Mac's Bedo a routine of its own in the same group when it sleeps at night.
Health
Health is shown, not said: nothing about it is posted into a thread, so no Bedo reacts to a machine going away unless somebody asks it to. The Fleet board and the list show how long an offline machine has been gone, mark a machine that is answering late because its inbox is far behind, and flag one on a different build from the rest. A turn that has run for a while shows how long under the thread. /fleet says the same in a thread, and an agent reads it with the bedos_board tool.
What the host sees
Everything said in a thread is stored on the beam host, readable by the people in it and by whoever runs the host. Credentials a message carries are masked before it is stored, and the message says how many were. A thread is kept 90 days after its last message.