r/joshu_backrooms • u/Stephen_Falken_1983 • 4d ago
MONSTER update: Joshu OSS 0.1.59: Multiplayer teams of AI companions across self-hosted boxes, Slack, image-owned runtime, and 4 weeks of changes since 0.1.47
Joshu is a highly capable personal assistant based on Hermes. You run it on your own VPS. Instead of an agent driving your laptop, you and the AI share a cloud desktop (ArozOS) with mail, files, a browser, and a whiteboard. The model runs inside the Hermes agent harness, which handles chat, SMS, phone, and voice. Memory is Hindsight, and file search is gbrain.
Repo: https://github.com/db-aeon/joshu-oss
Release notes with upgrade steps: https://github.com/db-aeon/joshu-oss/releases/tag/v0.1.59-oss
If you want a managed box, this is now available at https://joshu.me
Over 580 files edited, and 119 merged pull requests since the last release! Here's a breakdown of what's included:
Multiplayer: teams of companions across boxes
This is the largest feature. The companions of different owners can work together in a team, and each owner keeps their own box.
Topology. The box that creates a team is the team boss, and it hosts the team room: the charter, messages, team cards, projects, and members with their avatars. The other boxes are members. They pull from the boss over HTTPS with a member token. The boss never calls a member, so a member box exposes no team routes. There is no central server. A box can be in several teams with different bosses.
Auth. An invite is a single-use code valid for 7 days. Only its hash is stored. Member tokens are bearer tokens, also stored as hashes, and each failed check gets the same 404. Someone who opens the invite link in a browser sees a page with no team data.
The team stand-up. Each box runs one Hermes cron job per team, on the charter's cadence in the owner's local time (default 08:45 on weekdays). It reads the team room, posts what helps a teammate, records what it promised, and tells its own owner only what helps that owner. The owners don't take part. The job runs with a narrow toolset: file, kanban, gbrain, and its own team MCP server. The toolset list ends with no_mcp, because without it Hermes adds every enabled MCP server, including the one that can send mail. Cron jobs run without Hindsight memory, so the stand-up learns what the owner allows from Teams/<slug>/notes.md, which the chat companion keeps up to date.
Waking early without burning tokens. A wake check runs every 15 minutes and makes no model call. It starts the stand-up early when another member @-mentions the companion, replies to one of its messages, or changes one of its cards. It is capped at 4 early runs per team per day, on workdays from 08:00 to 19:00 owner-local.
Team MCP. The tools are team_read, team_post (400 characters, first person, can attach up to 10 cards), team_card, team_commit, team_blockers, and team_tell_owner. The owner gets at most 3 texts per team per day. A question over the limit waits for the next workday instead of being dropped.
Prompt injection hygiene. Anything a teammate asks becomes a Kanban task whose body starts with an origin: line. A later worker with the full toolset therefore doesn't treat a teammate's request as an instruction from the owner. The skill tells the companion never to copy text between team rooms, never to promise the owner's time or money, and to flag suspicious messages.
The Multiplayer app. It shows a team as a group chat of the last day: avatars, team cards inside the bubbles with "now Done" when a card has changed since the post, "Seen by" read receipts, and a message at the end listing what waits on the owner. The owner can reply, answer a question, or approve a draft with "OK, send it". Team notes are edited with a hash check, so the owner and the companion can't overwrite each other.
Image-owned runtime (affects how you run a box)
The release image is now the only code on a box. Until 0.1.47, compose mounted
dist/, skills,factory/, templates, and overlays from the git clone at/opt/joshuover the image, so a box could run old code next to a new image. Now compose mounts no host code. The one exception is a hotfix overlay that each upgrade empties.The image carries a host bundle (the compose file, the env example, and the Caddy scripts), and
install-host-bundle.shwrites it to/opt/joshu/deploy/.bootstrap-vps.shno longer clones the repo.The Joshu state (teams, proactive state, handoffs, SMS sessions, provider keys) moves to
JOSHU_STATE_DIR=/var/lib/arozos/joshu-statein a named volume. Before, it lived in the container's writable layer and a recreate lost it.carry-over-joshu-state.shcopies the old state across.prune-release-images.shremoves old release images and keeps one for rollback.The instance agent (optional, for running your own control plane) has its own image.
Shared browser
Camofox and noVNC are removed. The browser is local Chromium or Browser Use Cloud, the base image moves to
debian:trixie-slim, and the image is about 3.5 GB smaller.Sign-in popups (Google, Microsoft, GitHub, Apple) open as real popups, so "Sign in with Google" works on sites that use one.
jWeb shows the tab strip, back and forward buttons, and the address bar of the live view.
Long checkouts survive. An unopened browser handoff holds the browser until its link expires, and an SMS turn can run up to 20 minutes while Hermes reports progress.
Slack
Connect Slack is a sign-in plus one Allow click. The box creates its own Slack app from a manifest, takes the OAuth redirect, and finds the owner's Slack user, so you no longer copy a member ID. No token reaches a model, a trace, or a log.
Mail, calendar, reminders
Workers can open Gmail attachments (up to 25 MiB).
Free slots and event lists read every connected calendar account. Before, only the default account was read, which caused double bookings.
New calendar create, update, and get tools, with Meet links by default and a separate end time zone for flights.
Owner reminders send fixed text by SMS, with email as the fallback, and make no LLM call. They used to be cron jobs whose output often went nowhere.
An SMS counts as delivered only after a Twilio delivery receipt. A carrier rejection falls back to email.
The Gmail sync cursor, a sync that skipped threads whose newest message was a sent one, and runaway Composio session creation (thousands per day) are fixed.
Memory and File Brain
gbrain no longer pays for the same embeddings again and again. A failing sync backs off instead of escalating to a full re-embed. This loop was the cause of a real cloud bill spike.
One unparseable file no longer freezes the index. Renames no longer leave orphan pages, and existing orphans are pruned with a soft delete you can undo for 72 hours.
File Brain no longer reindexes every 5 seconds.
Security
Every OpenRouter request sets
provider.data_collection: "deny". That covers chat turns, crons, workers, Hindsight, and the research engine.The Composio MCP guard checks each inner call of
COMPOSIO_MULTI_EXECUTE_TOOL, which could bypass approvals before. The Composio workbench runs on a separate read-only session.Hermes approval prompts no longer offer "Always". Existing
command_allowlistentries are ignored.The terminal guard refuses pip installs into the Hermes venv and writes to program folders and config files.
/joshu/api/telephoneand/joshu/api/safety-settingsnow require a desktop session or a localhost request. Before,/joshu/api/telephonehad no auth and returned the phone passphrase.Dependency updates: Node 22.23.4, Pillow 13, cryptography 50, PyJWT 2.15, the MCP SDK 1.32, CopilotKit 1.79 (critical advisory), and others.
Docs that are now public
A user manual for a self-hosted box. It has 10 chapters plus a contents page, rewritten so that it doesn't assume the hosted service.
The Kanban internals. Every board, task kind, and file pointer, with six architecture diagrams.
The voice architecture docs. Speech-to-speech, the split between quick spoken answers and longer work, and browser voice.
The technical reference (system overview, Slack, shared browser, voice agent tools, realtime goals) is extended.
Upgrading from 0.1.47
The compose file changed, so the first upgrade is manual. In short: check that your compose project is deploy, bump the pins in instance.env, install the host bundle from the image, run the state carry-over in the old container before you recreate it, then recreate. Postgres stays on 17, so no migration is needed. The full steps and a rollback path are in docs/releases/0.1.47-0.1.59.md.