MURAGE
How it worksFeaturesSolutionsUse casesComparePricingDocs
DownloadDownload
MURAGE

An AI Chief of Staff and a team that does the work. Free and open source, from Ferrox Labs.

Product

  • Features
  • How it works
  • Engines and apps
  • Privacy and security
  • Pricing
  • Murage Cloud
  • Download
  • Changelog
  • FAQ

Solutions

  • Solopreneurs
  • Founders and startups
  • Agencies
  • Ecommerce
  • Small business
  • Creators and educators
  • Developers
  • SaaS
  • Nonprofits
  • Consultants and freelancers
  • Customer success teams
  • Legal and professional services
  • Small teams
  • Sales teams
  • Operations managers
  • Industries
  • Use cases
  • Build your team

Compare

  • vs Claude Code
  • vs Codex (ChatGPT Work)
  • vs Claude (Cowork)
  • vs Paperclip
  • vs OpenClaw
  • vs Hermes Agent
  • vs Manus
  • vs Genspark
  • vs n8n
  • vs Zapier
  • vs Grok Bot
  • vs Viktor
  • vs Lindy
  • vs Tasklet

Resources

  • Docs
  • Team library
  • Skill library
  • AI Chief of Staff
  • How we test
  • Limits
  • Switching to Murage
  • Open source
  • Blog
  • Release notes

Company

  • About
  • Partners
  • Enterprise
  • Contact
  • Privacy
  • Terms
  • Cookies
© 2026 Ferrox Labs. Murage is open source under AGPL-3.0.
Changelog

Murage 0.1.52

Released September 12, 2026. Murage tells you when an update is ready. You choose when to install it.

Download Murage

Free and open source. macOS, Windows and Ubuntu.

This release gives every bot a workspace you can see and edit beside the chat, lets a bot ask you a real question and get a real answer, brings local models into the product as a first-class setup, moves connected apps onto your FluxRouter account, and adds inline images, audio and video that never leave your machine unverified, including saved-file cards that show the file right in the chat. Underneath it, the engine runtime, the desktop process, the companion, the installer and the hosted broker each close a set of audited gaps, Stop means stop on every engine, and all seven language packs are complete.

Added

A workspace pane beside the chat. A resizable Workspace rail on the right of the conversation (chat keeps at least 360 px, rail at least 320 px, width remembered), a covering overlay with Back to chat on narrow screens, and an Expand mode. The rail lists the selected conversation's files, opens them in tabs named by scope and relative path, and previews Markdown (rendered or Source), protected HTML in a sandboxed frame, plain text, images, and a truthful open/download fallback for everything else. A single click reuses one clean preview tab; Keep open and Edit make a tab persistent; a dirty tab is never replaced and asks before it closes. Actions: Save, Save a copy, Save this version, Download, Open in app, Show in folder, Open in Files.

A Markdown editor that only writes on Save. Rich editing runs on Tiptap 3.31.3 and opens a file in rich mode only when the pinned parser is proven to round-trip that file byte for byte; anything else opens in Source mode on the exact text. Reloads never become edits. Saves are conditioned on the revision you opened: a file a bot changed underneath you becomes a conflict that shows both texts with Use the disk version / Keep my version, and a save while a bot turn holds that folder is refused with a plain message and nothing written. The revision you replace is kept as a saved version in Files first, so nothing is overwritten unless it was retained. Unsaved typing survives a crash: drafts live in the renderer (50 drafts, 10 MiB), are labeled separately from "File saved", and a recovered draft found after you started typing is held until you choose.

Files shows the workspace, not only saved copies. Files now carries both halves: the conversation's working folder as it is on disk right now (lazy folders, breadcrumbs, name search with an honest "incomplete" state, 200 entries per page) and the saved versions that never change. Every row is labeled "Workspace file" or "Saved copy". Legacy conversations pinned to no workspace and remote runs say exactly that instead of listing your home folder. Open in app and Show in folder hand one live file to the OS through an owner-bound, extension-allowlisted bridge that re-checks the file's identity immediately before the call.

Bot outputs are saved automatically. A file a bot writes into the managed outputs/ folder of its task workspace during a turn (regular files up to 25 MiB, at most 20 per turn) becomes a verified saved version in Files with producer and run provenance and one host-authored card in the chat, with no register_artifact call. A failed or canceled turn leaves the receipts retained and registers nothing. Generated images are receipted before they are attached, so an interrupted publication resumes on restart from the retained bytes with zero provider calls and no duplicate message.

Saved-file cards show the file itself. Every "Saved file" card in the chat previews inline instead of sending you to Files: images render in place and open the lightbox; audio and video embed the same player card (no autoplay, one at a time); Markdown, text and code show a bounded slice (2 KB, Show more up to 256 KB) rendered like the transcript; HTML renders in the same protected sandboxed frame Files uses; PDF and binaries keep their buttons. Open here still opens the working file in the workspace pane. Source and configuration files a bot writes (.py, .ts, .sh, .yaml, .toml, .sql, .go, .rs and the rest) are now saved as text so they preview too; .svg, .env, .pem, .key, archives and binaries stay download-only. The card never builds a raw bytes URL and refuses any resolver answer without a capability.

A question card, end to end. When Claude Code, Codex, Fuigo, an ACP agent or Pi asks you a question (AskUserQuestion, requestUserInput, ask_user_question, elicitation, select/input/editor), Murage now shows a card with the questions, options, descriptions, multi-select, Other and free text, fully keyboard-driven (1-9, Tab, Enter, Esc), and sends the engine exactly the answer shape it documents. A question is never auto-approved, never remembered as "Always allow" and never auto-reviewed; skipping it is delivered at once instead of leaving the engine waiting. The engine waits 30 minutes; after that the card stays as Expired with "Send as a message" so a late answer still reaches the bot. Cards persist across restarts. A URL elicitation is shown as a link you open; Murage never fetches it for you. The card reads like the other transcript cards: each question is a recessed sub-card, options are separate pills with an accent edge when picked, the key map lives in the Send button's tooltip, and an answered, sent or skipped card keeps its picks and settles into an "Answered · time" footer.

Questions on Telegram. The same card reaches the paired Telegram owner as its own message per question: numbered options with one inline button each, multi-select toggles with Submit, "Reply with text" for a free-text answer, and Skip. Answers go through the same validation as the desktop card; a stale, forged, foreign or expired tap does nothing. Secret questions stay in-app.

Local models, as a real setup. Settings → Models gains a permanent Local models section that says which addresses automatic detection checked (Ollama, LM Studio, llama.cpp, vLLM, SGLang), lets you add, edit and remove your own servers (loopback, home network or tailnet over plain http; https otherwise; key write-only), and runs a seven-check tool-calling test per model with a one-sentence outcome ("Tools work, ready for agents", "Context too small for agents") and the checks behind a disclosure. Loaded context is read from the server; Ollama gets a "create a 64K copy" action. Fuigo, Pi, OpenCode, Qwen Code, Hermes, Droid and Kimi are wired to a tested model; Codex and Claude Code rows appear only after their own surface test passes. The picker's Local rail shows "model · server" and marks a model whose tool test failed. Live proof against a llama.cpp Qwen3.8-27B host: four engines completed real tool-using turns.

Inline images with a lightbox. One accessible image surface for attachment galleries, Markdown images, screen frames and the Files saved-copy preview: a native modal dialog with focus trapping, Arrow/Home/End navigation inside the message's own set, alt text, reduced-motion support, contain-never-crop thumbnails, and Download of exactly the bytes shown. Remote Markdown images are an external card until you click Load (fetched with no referrer); local paths, file://, blob: and SVG are never requested.

Audio and video players for a conversation's own files. A WAV, MP3, Ogg, M4A, MP4 or WebM path in a transcript becomes a player only after the harness confirms the conversation has a dedicated workspace, the exact relative path is a regular file inside it right now, and the bytes are a type this build streams. Playback goes through the authorized byte route with a short-lived capability; the path itself is never fetched. No autoplay, metadata preload, one player at a time, seeking through range requests, Save a copy on every card including the ones that cannot play. An expired capability is renewed in place mid-listen.

"Use as reference". From the lightbox, add a conversation image (uploaded, generated or a saved PNG/JPEG/WebP up to 10 MiB) to the next message as an ordinary attached-image chip, so the bot can pass it to generate_image. Bots get a resolve_image_reference tool that pins uploaded, generated, saved or workspace images to exact bytes (up to four, 20 MiB total) and discloses what it prepared before any approval.

Image edits on xAI and OpenRouter. grok-imagine-image-2.0 edits one to four reference images through xAI's JSON edit endpoint; OpenRouter openai/gpt-image-2 sends references only when the pinned openai endpoint advertises a compatible range (checked within 15 s just before approval, fail closed, no fallback). Each provider's key is attached only to its own exact origin. Image settings now show each model's true edit capability and reason ("Creates and edits images", "Creates images only: …") and the reference limit it accepts.

Connected apps through FluxRouter. Connected apps can now run through a FluxRouter account. The FluxRouter key is spent once, in the main process, to mint a broker token that never reaches an engine subprocess, so a shell command a model runs can never read your Gmail past per-bot policy. An existing install's Composio identity is adopted, not copied, through a three-leg claim (sign, redeem, confirm) so a stranded migration loses nothing; a personal account auto-claims, a shared team account moves only on an explicit button. FluxRouter claims are on for this release: the Worker has issued them since rollout step 5 and FluxRouter has redeemed them since step 6 (2026-09-11), and the committed Worker config ships CLAIM_MODE open with new-install registration closed (step 8, the day this release publishes). This build is pointed at the FluxRouter broker (https://api.fluxrouter.ai/composio) and the Murage-hosted Worker broker is used for existing connections only until 2026-11-10T00:00:00Z (rollout step 7); after that date a connection that was never claimed onto a FluxRouter account is no longer served.

The Connected apps panel earns its key first. Until a FluxRouter key or your own Composio key exists, the panel is a dimmed, inert showcase of 24 well-known apps under one headline and one action ("Add FluxRouter key", straight into the Flux key field; "Have your own Composio key? Add it under Advanced." as the secondary path). While locked it makes no connector request at all; the moment a key is saved the panel opens, no reopen needed.

Operators the Chief creates inherit its Auto, narrowly. A bot the Chief creates with create_bot starts in Auto only when you already put the Chief in Auto in that conversation and the turn is not unattended; otherwise it starts in Ask. The inherited Auto is strictly narrower: computer off, no peer comms, no Composio, an empty always-allow list, and every existing Auto guard (destructive actions card, questions are never auto-answered, credentials land as a secret card). The Chief is told which operators will ask.

Unattended murage for provisioning. --non-interactive / --yes / MURAGE_NON_INTERACTIVE never prompts; anything missing is listed all at once and the run exits 2 having changed nothing. Secrets come from a file, stdin or the environment, never from argv (--provider-key <value> is refused by name). Every choice has a flag and an env form; exit codes are documented (0 secured, 1 cannot run here, 2 incomplete request, 3 not on the tailnet).

Save a code block. Chat code blocks gain Save beside Wrap and Copy: exactly the bytes Copy would copy, a file name from the fence language (Dockerfile and Makefile keep their names; launcher extensions fall back to snippet.txt), no network request.

Engine lifecycle diagnostics. ACP children (Fuigo included) record a bounded, secret-refusing engine_lifecycle trail (spawn, RPC, stop route, settle, close) with a per-process generation, written to the existing 0600 native log, so an engine incident can be read from evidence.

Enhanced

A chat header that measures itself. The header tries layouts richest-first until one fits with a usable name track: fold role, usage and Inspector into a keyboard-accessible More menu, trim chips to icons, take a deliberate two-row header, then relocate controls. Bot identity, Stop, the task/model context and Call never move. It reacts to the chat container, not the viewport, so an open sidebar folds it the same way. Proven at 320 to 1024 px, 200% text and long pseudo-locale labels. The folder chip opens the effective workspace and names the resolved location.

Sidebar rows stay clickable. A bot row keeps its full hit area during rename, and the invisible disabled Archive control that swallowed clicks on the Chief, team leads and the last bot is gone; the More menu still explains why Archive is unavailable.

Long inline code and link labels wrap inside the bubble instead of pushing a table or the transcript into a sideways scroll; fenced blocks keep their horizontal scroll and wrap toggle.

Local contention gets local advice. A thread refused because another thread holds the same folder, computer or browser profile shows a "Waiting on another thread" card with wait/stop/retry guidance instead of the provider-settings card.

Stop means stop, on every engine. Pressing Stop on a running Claude, Codex, Antigravity, OpenAI-compatible, Grok, MiniMax or box turn now settles as a quiet stopped state, the same one ACP and Pi already used, never the red "This request hit a problem" card with Retry, and the memory record says canceled, so a stopped turn's unfinished intentions stay out of consolidation. A stopped turn is never counted as finished work: it publishes no outputs/ file, its queued handoffs are dropped, ask_bot reports the stop instead of a reply, a routine run the host stopped fails rather than completes, and a stopped room member is treated as a provider failure. When the host stops a turn itself (model connection changed or turned off, computer switched off for the bot) a neutral "Stopped, reason" row is shown even with Tool calls off, in the transcript, the sidebar preview and the task timeline. Stop then Restore, and Stop then Save in the workspace editor, wait for the stopped turn's folder lease (bounded by the engine's close budget) instead of refusing with "another turn is using this folder".

Messages have one honest size limit. A message is bounded at 1 MB of text on both sides. An over-limit message is refused inline, before any request and before the draft is cleared, with its size and the limit stated in human units; the text and attachments stay put, and a 413 the harness answers lands in the same place instead of a passing toast. Previously a 4 MB paste sent nothing and said nothing.

Auto on a fresh Mac bot asks the warning it should. Turning Auto on from the composer chip or the profile switch for a bot that never chose a computer (which resolves to this Mac) now opens the "Allow Auto mode on this computer?" warning instead of a red "requires confirming the warning first" banner with no warning to confirm. Both the thread route and the profile route apply the same rule, decided on the harness's platform rather than the browser's user agent. The acknowledgement is still never persisted.

Images send while the engine list is still loading. A "Use as reference" chip or a pasted image right after opening the app is no longer refused as "the selected responder does not support image attachments" because the engine list had not answered yet; an empty list means "not asked yet", and an engine that truly lacks image support is still refused once the list is loaded.

Claude accounts respond at once. Adding, renaming or removing a Claude account draws from the server's receipt before the engine re-probe, the list is fetched without snapshotting every engine, a slow list answer can no longer redraw over a newer change, and the section stays usable during the Engines fleet refresh (a failed refresh reports itself without greying the buttons). The model picker keeps its catalog when only the engine fleet probe fails and shows that as a secondary line.

Remembered notes reach the engine as words. Memory context is delivered as attributed lines inside a <remembered-context> frame with a preamble that says these are notes, not the request and not a reply template, record ids, scope ids and evidence byte ranges stay Murage-side, in the disclosure receipts and the memory tools. Each line opens with an opaque turn-local handle (m1, m2, …) that memory_get and memory_propose_correction accept; a handle resolves only through the receipt of the dispatch it was minted for. A turn's own messages are kept out of its recall, a whole serialized room round is kept out of a member's recall, and a provenance-only reply is never presented as the answer. Recall quality before and after is recorded in docs/plans/0152-MEMJSON2-RECALL.md.

A workspace revision names the bytes. A file's revision now carries the SHA-256 of its content (for every file the editor can read or write), so an equal-length rewrite inside one filesystem timestamp tick, routine on ext4, HFS+ and network shares, can never pass as the old revision: Save version never copies bytes you did not choose, a Markdown save based on a stale revision cannot replace someone else's edit, and a kept or saved version whose bytes are not the verified revision is refused. Digests are remembered only on volumes that pass a per-device clock probe, so listing stays fast without trusting a mirror or whole-second mount.

First Composio account gets a label. Connect now opens the label form for the first account too, with Cancel and Escape, so an account is never created under a generated id.

Memory corrections reviewed precisely. Approving an agent-proposed correction validates the exact target revision, supersedes only that record (kept as history) and, when the target is pinned, requires an explicit transfer-or-unpin choice with nothing preselected.

Routines keep a due run across an edit. Renaming, changing instructions or the timeout of a routine after an occurrence became due no longer moves that occurrence into the future; a changed schedule still recalculates.

Screen frames settle under every tool spelling. A screenshot reported as computerscreenshot (server-qualified, no mcp prefix) now counts as screen work and settles its frame in the transcript.

Grok, OpenAI-compatible and MiniMax streams are judged honestly. A stream completes only with [DONE] or a finish frame followed by clean EOF; an in-band error, a truncation or an empty reply fails the turn with its reason, and the text that did arrive is kept on the failed message rather than dropped.

Pi runs the model you picked. A rejected or timed-out set_model (or session handshake) fails the turn before any prompt is written instead of silently running Pi's default; a bare model id fails before a child is spawned. Pi's host-computer asks carry the local-computer scope so they are never remembered as "Always allow" or auto-reviewed.

Fuigo bundle 1.0.13. Every target tarball checked byte-identical to the upstream release-workflow artifact (run 34623419288, source 1f5f89ab; no GitHub release v1.0.13 exists, the workflow publishes npm only) and SHA-512/SHA-1 against npm integrity/shasum and the run's release manifest; third_party/fuigo provenance updated. 1.0.13 is the first published Fuigo whose folder-trust gate is live (1.0.11/1.0.12 binaries were dev-stamped and auto-trusted every folder): a hosted turn in a folder the user has not trusted in Fuigo runs without that folder's repo-local MCP/hooks/permission rules and, new in 1.0.13, its AGENTS.md/CLAUDE.md and project skills. It never blocks (no prompt on a piped stdio session). auto mode stops auto-running discarding git checkout/switch/stash and rg --hostname-bin; those now reach Murage's permission card. The 1.0.12 ask_user_question gate and question card path are unchanged.

Folder trust is a question, not a silent loss (FUIGOTRUST1). Left alone, 1.0.13's gate would have dropped every workspace's AGENTS.md, CLAUDE.md, .mcp.json, skills and hooks from every hosted Fuigo turn unless the person had run fuigo --trust in a terminal. Murage now asks once per folder: a folder chosen in a working-folder picker is trusted when it is chosen (the picker says so), and any other folder with those files, a bot-created folder, a clone, a subfolder with its own repo, raises a "Trust this folder?" card naming what it contains, before the engine starts; the answer is remembered per folder (Settings shows it, with Forget). Trust is passed to Fuigo as --trust, so the same turn reads the instructions; Don't trust runs the turn without them and the conversation shows what was left out; nobody answering in time ends the turn as a stopped turn. Auto mode never trusts a folder, and only the desktop or the paired Telegram channel can. Murage also advertises Fuigo's interactive trust capability and answers its request from the same decision. Proven against the bundled 1.0.13 binary on a local model: an AGENTS.md canary is absent untrusted and present the moment the card is answered Trust. Follow-ups (FUIGOTRUST2): folders your bots were already working in before this release are treated as trusted, you chose them in Murage, so the upgrade raises no card for them (Forget in the picker asks again); a folder you trusted in standalone Fuigo (fuigo --trust) is honoured as trusted here too, with no card and no "untrusted folder" notice, and the picker says which install trusts it; a card the engine raised on its own that the turn outran now says the turn ran without the folder's files instead of "stopped"; folder trust is recorded from a picker only on the desktop, including a team imported as a project; and a provider-routed turn that never started (card stopped or timed out) no longer leaves its temporary Fuigo home behind. Further follow-ups (FUIGOTRUST3): a bot working in a linked git worktree shares its trust with the main checkout, exactly as Fuigo keys it, so fuigo --trust on the main repo covers every worktree and a worktree picked in Murage is remembered for the whole repo; a folder Fuigo itself still asks about is never trusted on Murage's reading of Fuigo's store alone, your own answer, or the card, decides; a card the engine raised on its own under a turn that then failed says the turn failed, not "stopped"; and the picker note reads the Fuigo install of the bot it belongs to when several Fuigo instances run with different homes. Last (FUIGOTRUST4): a fuigo -w managed worktree is keyed on its recorded source repository exactly as Fuigo's own workspace_key does (read-only, never creating the registry), so a bot working in one no longer sees a trust card the engine would not raise; the default Fuigo home is canonicalized the way upstream does; and a room's folder-trust note describes its Fuigo members, once when their verdicts agree, per member when they differ, and names a refused turn or an engine that gates no folder before any trust verdict. The mirror's known limits are recorded in third_party/fuigo/README.md.

Images can be saved without touching the source. Choosing the source file itself (or a hard/symlink alias) as the Save destination is a no-op rather than a truncation; every other destination is written to an exclusive sibling and published with one rename.

Installer ergonomics. setup reruns keep every stored provider key and custom setting unless you replace one; the env file is published atomically with a .previous copy; secrets are read with no terminal echo and no readline history; setup and start refuse a Node below the payload's floor (24) before any side effect.

Installer, proven on Linux. Five changes from a live Ubuntu 24.04 proof under real systemd and Tailscale: tailscale up carries --reset so a rerun can repair a failed enrolment instead of being refused for "non-default flags"; the unit grants the data directory's parent, where the server keeps its installation lease, so the service no longer dies at every start under ProtectHome; murage status --service-user <account> looks where a root setup put the deployment instead of root's own home; start waits (up to 90 s) for tailscaled to report the verified proxy after a boot, so the first requests through the tailnet are not 403; and an unattended run refused for a missing input creates no data directory. The README's exit-code table now says a failed Tailscale install exits 3.

Companion registry that cannot lose a fleet. An unreadable devices.json marks the registry unavailable (pairing answers 503, the bytes stay untouched) instead of being treated as an empty first run; a failed revoke write rolls memory back and answers a sanitized 500 with the streams untouched.

Docs and control-plane dependencies patched. next 16.3.3 and vitest 4.1.11 in their own packages only; the desktop lockfile importer is byte-identical. pnpm audit --prod goes from 2 Critical / 4 High / 3 Moderate to 0 / 4 / 1, with the remaining sharp and adm-zip advisories assessed as not reachable and recorded.

Hardened

Engine stdout is byte-bounded before it is parsed. ACP, Claude, Codex and Pi frames are capped at 32 MiB; an oversized or never-ending frame fails only that turn with frame_too_large, is never truncated and parsed, and nothing after it can settle the turn as a success.

Claude never replays a turn after its prompt was written. A relaunch happens only when the prompt write was refused and no output was seen; a written or in-flight prompt fails visibly. Tool use, tool results and reasoning now count as output.

Stop means the child is gone. ACP and Pi confirm the child's close before a thread's folder, computer or browser lease is released; an unconfirmed stop keeps the run "stopping" with its leases held and a visible notice, so a same-folder replacement stays refused while the stopped engine is alive.

Existing engine configs are never rewritten blind. A Qwen Code, OpenCode or Antigravity config that cannot be parsed (including valid JSONC the CLIs accept) is refused with repair guidance before any write; the file keeps its bytes and the turn fails before the CLI spawns.

VM / VPS held-control fails closed. A timeout, non-2xx answer or malformed body from the control endpoint means "unknown", not "free", and the MCP bridge refuses tool calls with reconnect guidance.

Every privileged desktop IPC is bound to the owned main frame. Secret issuance, screen capture, credentials, companion, updater, CUA, Android, speech, recorder, permissions and native actions refuse any other window, subframe or navigated-away origin before a listener runs; the main window cannot leave its renderer origin, and credential-free web links open in the default browser. The preload exposes the bridge only on the origin main passed at launch.

Main-app permission allowlist. Notifications, clipboard, fullscreen and audio media are allowed for the owned main window's top frame; camera, devices, mixed media and foreign origins are denied; display capture stays intent-bound and one-shot. A disposable-profile smoke proves it on macOS in CI.

Recordings and saves land in the installation you are running. Skill recordings and Save go to the active owned root (never ~/.murage by fallback), are sender-authorized, and are refused during recovery, while closing or without ownership.

Speech and recorder helpers stay owned until they exit. A failed stop-marker write keeps ownership and is retried on the next Stop, Start or Quit; Quit waits for the helpers (10 s deadline) and reports an incomplete stop instead of claiming clean cleanup. Nothing is killed by process name.

Provider credentials fence on an uncertain write. A provider-bank replace whose acknowledgement is lost fences provider writes and new dispatch until a revision readback confirms the state; an unknown successor revision is never overwritten.

Bare xAI, Groq and Hugging Face keys are masked in stored bot text, native logs and canonical events.

Companion streams end with their session. A browser's event stream is bound to its session identity and closes on sign-out, eviction by a newer sign-in, or expiry, not only on device revoke. The SSE scrub fails closed: a payload that parses but cannot be scrubbed ends the stream rather than being forwarded raw. An explicit tailnet bind requires Tailscale's own confirmation of the address; a carrier-NAT or VPN address in the same range no longer satisfies it.

Installer runs the service as a named non-root account. The systemd unit always carries User=, Group=, HOME and UMask=0077; setup as root requires --service-user and does that account's file work as that account, never as root by path (a planted symlink can no longer redirect a root write). The unit is staged privately with a digest-checked install command, and unit fields are escaped the way systemd parses them. Every murage start writes a fresh door-identity nonce; setup and status front a listener only after it proves that identity and version.

Composio broker (source only, not deployed). Registration throttling keys on the edge source address (IPv6 by /64) instead of a client-controlled User-Agent; request bodies are streamed and canceled at their caps before any charge; a failed account inventory refuses new links with 503 instead of linking blind; the call ceiling counts tool executions only. Control-plane connector-token issuance is fenced by the exact authorizing credential so a revocation or rotation in flight withholds the token.

Files discovery never lists Murage's own data folder and re-checks the folder chain after describing each page, failing with root-changed if a folder was swapped for a link in the window.

Release publication holds until every asset digest is proven. A missing GitHub digest after the bounded wait fails the proof step with a HOLD; the draft is left untouched and a rerun reuses the build artifacts without re-uploading.

Quality

All seven language packs complete. German, Spanish, French, Hindi, Japanese, Brazilian Portuguese and Chinese carry all 525 English strings, drafted with the repository's Claude-CLI flow, reviewed, and recorded against the exact English source each translates, so pnpm i18n:check is green and a future English change flags the stale translation.

Baseline red suites repaired, not skipped. server/index.test.ts (17 failures at the 0.1.51 baseline) is 237/237: four thread-era behaviors tightened so the suite's expectations hold (delete-guard order, read-state body validation, explicit channel-thread interrupt, package import rewriting persisted bots) and the rest re-aligned to recorded decisions. The Electron data-owner and memory-profile fixtures evaluate the real main.mjs slices again. A new main-module-load test proves the Electron main module still loads with every handler registered exactly once.

Concurrency proof runs the real scenario on every platform (macOS host control, Linux supervised driver, Windows refusal before the engine starts).

One gate in front of every recursive delete in the test tree. After a 2026-09-11 incident in which a test run on a shared build machine wiped a developer's live ~/.murage, every recursive delete a test or script performs goes through safe-wipe (Node and a shell twin): a target may be deleted only under the OS temp dir, a scratch or evidence path, or strictly inside a caller-named build root, and never when it is, contains or lies inside ~/.murage, the companion dir, a non-scratch data dir, any home, the cwd or a filesystem root, or beside a live installation lease. The guard is installed into node:fs for every vitest and node --test process; a tree-wide test proves every recursive delete is routed or allowlisted with a reason; human specs require MURAGE_E2E_DATA_DIR and keep their evidence out of the checkout.

Rooms and memory never lose a turn. A member turn whose memory context is revoked mid-dispatch (a task created for the member while its room handshake was held) is re-dispatched once instead of refused; every exit between the room claim and an accepted provider turn releases the room, the bot, the browser capability and the round's skill claim through one path and drains the queues, with a stopped notice, so a room can no longer sit silently stuck; a stale exit never idles a room another owner took; a delegation retry that lands while provider admission is closed is kept; delegations and coordination slots are settled for runs retired by a provider reload; and a memory job whose publication is refused as stale is requeued at once, with the stale-lease requeue bounded at five.

Release-branch suites repaired, not skipped. The failures the CI rehearsal and the candidate verifier found on the release branch (updater lifecycle wiring, delegation finalize on provider reload, the unattended webhook question, onboarding/dialog/menu pins, the token sweep, the settings role reader, and the p01/p05 memory snapshots refused by the 0.1.52 saved-file and inbox tables) were fixed at the source or their expectations re-aligned to recorded decisions, and the order-dependent and load-bound fixtures (steering, delayed-body, claude-accounts, stop-state, question-skipped, checkpoint restore) wait on the event they need instead of a wall-clock window. p06 names a missing pinned-model fixture instead of failing obscurely.

Joined proofs. Real-harness Playwright specs for the workspace editor (shell-written report → card → Open here → edit/save → competing bot write → restart), media publication (one generation, one asset, one saved result, recovery with zero provider calls), media players, the question card against the real Claude CLI, the responsive header, local models in the real renderer, sidebar hit areas, connected-apps alias, code-block Save, saved-file cards (390 and 1200 px, both skins), the stop state, Auto consent, Claude accounts under a held fleet probe, image-settings capability truth on keyless and keyed installs, the message size bound, and a real-app proof that Fuigo on Flux Auto sees remembered words rather than provenance JSON. A joined 0.1.52 scenario driver (docs/plans/0152-CANDIDATE.md) records the integration candidate.

NOTICE lists every adapted upstream change (#987, #986, #1023, #762, #767, #758, #979 adapted; #988 and #920 behavior taken, written independently) with the exact upstream commits, per Apache-2.0 section 4.

Still open in this release

The customer engine incidents (-32603 and exit 1073807364) are not closed by anything in this candidate. The lifecycle diagnostics above are the evidence path; a matching trace is still required to call them resolved.

The MEMORY_CONTEXT_REVOKED harness incident (a turn canceled before any engine starts when memory data is written between bundle build and dispatch, about one run in four on the shared build machine) is recorded in docs/plans/0152-CONTRACTS.md for the memory owner, not fixed.

Not covered by the close-confirmed stop contract: Antigravity and BoxAgent (documented in server/contracts.ts).

Downgrading to 0.1.51 after running 0.1.52 is not supported: 0.1.52 adds two columns to the saved-files table and 0.1.51 inserts positionally. The updater never downgrades; this only affects a manual reinstall.

Checkpoint Restore is API/agent-only in 0.1.52 (recorded in docs/plans/0152-CONTRACTS.md).

Native gates still open: real macOS helper exit and released mic/event tap (R2-T4), Finder open/reveal (F4-T5), a real CGNAT host with no Tailscale CLI (S1-T7), one live image edit per provider (F1-T5), packaged inference smoke (Q1-T3). The Linux installer proof under real systemd/Tailscale (F2) closed with LINUXFIX; signing, notarization and the draft assembly were proven by the CI rehearsal on this branch.

Downloads and checksums on GitHubAll releases

Give your first job to Murage.

Download the free app, connect the AI you already pay for, and tell your Chief of Staff what needs doing. Plan on about ten minutes from install to a working team.

Free · Download Murage

No account needed · Runs on the AI plan you already pay for