Skip to content

v0.1.23

Choose a tag to compare

@github-actions github-actions released this 12 Oct 21:33
· 1406 commits to main since this release

Added

  • Signing in is a page in your browser. mecha-docs auth signs in with
    mecha's own Drive app, so Google Docs needs no Cloud console project.
    mecha-mail auth with nothing after it asks Google or Outlook and a name,
    and, the first time, walks you through registering your own sign-in app
    (mail ships none: a shared Gmail client would be a phishing kit under mecha's
    name), opening each console page in turn and picking up Google's downloaded
    client file; --client-json takes that file directly. mecha setup runs it
    on a yes. Sign-in pages now open on macOS too (open; it used xdg-open
    only), and Outlook's device-code page opens in the browser where there is one.

  • The installed image server gives its memory back. mecha features enable image now also installs mecha-comfyui-idle.timer, which restarts
    mecha-comfyui.service once it has held a model unused for 15 minutes,
    as the hand-built server's mecha-comfyui-idle-reset already did. A
    loaded server holds ~13.6 GB; a restarted one, ~1.1 GB.

  • Picture settings for chat. Settings → Images sets how pictures are
    drawn in every chat: model, steps, guidance, sampler, scheduler and the
    negative prompt. A persona's picture settings now fall back to these
    field by field and override any of them; a persona on a different model
    takes that model's own numbers. A persona's unset model or negative is
    now inherited rather than standard/off, so a persona with nothing set
    draws as the chat does.

  • Speech to text installs itself. On Linux, mecha features enable voice
    now offers the speech-to-text server: an environment built from a
    hash-pinned lock, the Parakeet model fetched by its pinned sha256, and
    mecha-parakeet.service started on :8992, all under
    ~/.mecha/sidecars/stt/. The model's 465 MiB counts in the plan's total.
    A Parakeet you already run on :8992 is left alone and used as it is.

  • The speech server installs itself. On Linux with an NVIDIA GPU and
    the CUDA toolkit, mecha features enable voice now also offers Breeze TTS
    2:

    • its engine, built from a pinned commit of the published qwentts.cpp port;
    • its converted weights and a default voice, fetched by sha256 from
      mecha-factory/mecha-speech-gguf and counted in the plan's total;
    • the adapter, from a hash-pinned lock;
    • mecha-breeze-tts.service on :8886 and mecha-breeze-adapter.service
      on :8887, checked by speaking a sentence.

    The weights are licensed for research and non-commercial use only, which
    the install says before fetching them. A speech server you already run is
    left alone and used.

  • The turbo image model is fetched on demand. mecha features enable image --turbo fetches it (6.8 GiB, by its pinned sha256) into the image
    server mecha installs, and mecha features enable image offers it unasked
    once a persona's picture settings choose turbo. A turbo picture refused for
    want of the file names that command.

  • The image server installs itself. On Linux with an NVIDIA driver
    580 or newer, mecha features enable image now offers ComfyUI: the pinned
    release fetched by its commit, torch for CUDA 13 and ComfyUI's
    requirements from a hash-pinned lock (about 3.6 GiB, counted in the plan's
    total), the three Qwen-Image 2.1 files by their pinned sha256, and
    mecha-comfyui.service on :8188, all under ~/.mecha/sidecars/comfyui/.
    With no [image] table in your config it writes one naming the server's
    temp directory; one you wrote is left alone. A ComfyUI you already run on
    :8188 is left alone and used as it is.

  • The voice worker installs itself. mecha features enable voice also
    offers the Pipecat worker: its environment from a hash-pinned lock, the
    worker run from a copy mecha writes, and mecha-voice-worker.service
    started on :7860 under ~/.mecha/sidecars/voice-worker/. It takes calls
    only through mecha serve's relay, so no hostname needs setting. A worker
    you already run on :7860 is left alone and used as it is.

Changed

  • mecha setup no longer opens an editor for the charter. A yes
    ran mecha charter edit, which took over the terminal mid-setup and ended
    setup wherever the editor left it. The step now says where to write it
    (mecha charter edit, or Settings → Charter) and setup carries on.

  • A local provider with no model asks for what its server serves. A
    [providers.local] on this machine that names no model used to send
    gpt-4o-mini — which a llama-server router does not serve, and which
    every session record then named as the model that answered. It now asks
    for the router's loaded model, or its only one, or a plain server's alias,
    read once when the command starts; a router with several and none loaded
    is reported rather than guessed at. The same holds with no config file at
    all, where the built-in local provider is the default.

  • mecha setup is one guided pass. At a terminal it asks about the chat
    model first — the one recommended for your machine, a GGUF you have, or a
    hosted model — then each feature as a yes or no with what it downloads, then
    shows everything and the total and asks once before installing it all. No
    more stopping to run mecha setup chat and coming back.

  • A new install uses a model on your machine, not Anthropic. mecha config init now makes the local provider (127.0.0.1:8080) the default,
    with Anthropic kept beside it for -p anthropic; mecha setup names mecha setup chat to install a local model when nothing answers there. An existing
    config is not changed — but one that never set default_provider now
    answers from 127.0.0.1:8080, and a [providers.local] that names no
    model or context_window is reported by mecha setup until mecha setup --write fills them in from the server.

  • mecha features enable no longer installs the chat model. Switching
    on the web app or documents used to offer the chat model's ~22 GiB download
    on a machine without one; the chat model is chosen and installed by mecha setup chat, and enable installs only what the feature itself runs.

  • Each picture's prompt is saved for you, for now. Beside every kept
    chat's transcript, <chat>.prompts.log holds one line per picture: what
    was drawn, how, and the prompt the image model was given, so prompts can
    be studied and improved. Nothing reads it but you, an incognito chat keeps
    none, and forgetting a chat removes it.

  • A persona's picture shows what you asked for. A persona copying its
    own earlier picture calls often left your request out, drawing the same
    scene again. Each picture call is now checked against your words and the
    persona's last reply, and whatever the call left out (what people do,
    what they wear) is filled in. When you ask what the persona would like,
    the picture follows what it said.

  • Pictures of people doing something together put each of them in their
    own part.
    A persona describing an act between two or three people used
    to get a lineup, with the act applied between neighbours and sometimes a
    person drawn twice. The scene is now split into what each person does and
    where they stand before it is drawn, so whoever hands the cup is the one
    holding it out. It adds a second or two per picture.

  • A picture asked for while another is being drawn waits its turn instead
    of failing.
    A chat draws one picture at a time and keeps up to three
    more in line behind it, in order; a panel edit waits its turn too. A
    chat shows its line while two or more are out — the one drawing, with
    its clock, then the ones waiting — and each can be stopped on its own or
    dragged (or moved with ↑/↓) into a new place; the one drawing never
    moves. Stop on a picture stops that one; the call screen's Stop stops
    them all.

  • A picture asked for in a style the library doesn't have still draws.
    A model that wrote a look like "hyperreal render" or "oil on linen"
    where only a library style's name fits was refused every time, and in a
    persona chat it retried until the run gave up with nothing drawn. The
    style is now left out, the reply names the styles the library has, and
    the picture draws. A style written as words ("Digital painting") finds
    the library's digital-painting, and the tool's description lists the
    styles, so a persona chat can use them; locked styles and character
    names are never listed.

  • The image server stays loaded for a quarter hour after a picture. A
    picture asked for within 15 minutes of the last one is drawn warm: on
    2026-10-08 a cold one (the server restarting, then loading the model) took
    145–180 s against 36–63 s warm. The cost is about 14 GB held that long.

  • A retouch keeps who is in the picture. Edits got faster on 2026-10-08
    by sending smaller reference pictures, but a retouch has no face crop to
    carry who is in the picture, and at the smaller size faces drifted. A
    retouch, and any edit where someone in the picture has no face crop,
    now sends the picture at full size again; changing one person's clothes
    or expression in a picture of just them stays fast.

  • An edit from the picture panel is drawn by mecha itself, and the
    persona only answers.
    Your words and what the picture was drawn as are
    read into a typed change by a quick one-shot pass, the change is drawn,
    and the persona replies in a line or two without a tool. A painted area is
    drawn as written. A name the library doesn't hold, or a change that can't
    be read, is said on the card instead of drawn as a stranger, and nothing
    is drawn. Asking for another try draws the same scene again at a new seed.

  • Pictures are described as a scene, and the tool writes the prompt
    (IMAGE-DESIGN.md). image_generate takes a scene:

    • setting, which is everything but the people and the words, as text or
      a room photo;
    • light, camera, style, together (what the people do with each
      other) and text (words to render exactly);
    • people, each with who (a library name, self, or a description),
      where, wearing, doing and expression.

    To change a picture, name it in picture and send only what changes:

    • A new pose, the camera, the setting, the light or a removal redraws
      everyone on the scene's setting, so the camera actually moves and faces
      don't drift down a chain of edits.
    • New clothes, an expression, someone added or the words edit the
      picture, with a head crop of each person it changes.
    • Restating what is already true changes nothing, and a call that
      changes nothing draws the scene again at a new seed.
    • One small change to the picture itself goes in retouch, with a
      painted mask if there is one.

    Up to five people with faces fit one picture. prompt, cast, extras,
    edit, negative_prompt and reference_images are gone, and a chat's
    schema has no seed (mecha run and evals keep it).

  • Every picture remembers its scene. Each picture drawn in a persona
    chat, in the assistant's web chat, or in an incognito chat records where
    it is, who is in it, and what they wear and do. The incognito record stays
    in its room. A picture brought into another chat is recognised by its
    content and keeps its scene. Deleting an assistant chat, or forgetting a
    persona chat's memories, removes the records it wrote. Each persona turn
    is told what its last picture showed, so a remembered day's outfit or
    setting no longer slips into the present.

  • An edit carries the faces of the people it changes. Each library
    character an edit places or changes comes in as a head crop of their
    portrait, beside their description, so a chain of edits no longer drifts
    into somebody else. Someone is drawn only when listed as a person: a
    library name in the other words, for someone not in the picture, is read as
    "the viewer" rather than drawn as a stranger, and the result says so. A
    name still waiting for approval is refused.

Security

  • An experiment environment can no longer set [documents]. A project's
    mecha.toml was already stripped of it, but an environment's config.toml
    — which arrives with a checkout — could point OCR at a remote server or run
    the PDF parser unconfined. mecha exp now refuses such a file, as it does
    [image], [messages], [slack], [web] and [harness].

Removed

  • Break reminders and the farewell check are gone from personas. Both
    were switches on the settings page that did nothing yet; they were dropped
    rather than built. A persona.toml that still has breaks or farewell
    under [safety] loads as before, and the persona's notes say those lines
    are read by nothing and can be deleted.

Added

  • Picture settings per persona. A persona's settings page has a Picture
    settings panel beside the touching-scenes switch. It sets the model
    (standard or turbo), steps, guidance (cfg), sampler, scheduler and whether
    a fixed negative prompt is sent. Presets are offered for the default, a
    guided setting and turbo, with a rough time per picture. A persona nobody
    tuned draws exactly as before. Switching models unloads the other one
    first, and the turbo model needs one more file ([image] turbo_model).
    mecha replay --persona takes the same settings as flags.

  • llama.cpp is built on your machine when no release build fits it. An
    NVIDIA driver too old for the release's CUDA build, or a Linux
    architecture no release covers, used to get no engine at all; now mecha features enable and mecha setup chat build the same pinned version from
    its commit, checked the way a release is. It needs git, cmake, a C++
    compiler and, for CUDA, the toolkit's nvcc — anything missing is named
    before you are asked. mecha setup engine --upgrade still fetches release
    builds only, so a built engine moves with mecha's pin.

  • Regenerate a picture, and step through its versions. A picture in
    the assistant's chat or a persona chat has a Regenerate button beside
    Edit. It draws the same picture again at a new seed, with no words and no
    painted area, and the new one shows on the same card, with ‹ › to step
    between the versions, as soon as it is drawn. Edit, Regenerate and
    Download act on the version showing. Regenerate is off while the persona
    is answering. On a call, Regenerate is in the picture viewer: the persona
    answers aloud, and talking over the redraw does not stop it.

  • mecha replay --persona --rerecord replays an older chat as it would
    be recorded today.
    A tool call that ran away to the output limit is
    shortened to its start with a note, and the answer to it is the one the
    harness gives now, so a chat from before that fix is replayed with the
    history this build would have kept.

  • mecha replay --judge knows who is who. Each face in a judged
    picture is matched to the scene's library characters by their portraits
    (ArcFace, fetched the first time it is needed, with its non-commercial
    research licence stated), and each person's clothing and action is
    checked on that person, and on everyone else, so an outfit drawn on the
    wrong person is counted as a bleed.

  • mecha replay --judge scores a persona replay's pictures. For each
    picture a replay drew, it counts faces and people against the scene's
    record, and asks a vision model whether each thing the record says is
    in the picture (and, for an edit, whether it was already in the picture
    it started from). It writes the verdicts beside the samples and a
    contact sheet with one row per file, so two arms can be compared by eye
    and by count.

  • mecha replay --persona samples a persona chat's turn. It branches at
    one of the chat's turns (--list shows them) and sends that turn's first
    request again, --samples times with a different seed each, as the chat
    would send it today. --overlay tries a wording change. The samples go to
    a private file under ~/.mecha/research/replay/. The command waits while
    you are using the model or on a call. A picture the turn asks for is
    drawn, against the chat's scene as it was then, in a scratch copy that
    never touches the chat (--no-render skips it). --at-call branches
    partway through a turn.

  • The face detector behind edits. Head crops come from a detector that
    runs inside mecha: install it once with mecha imagelib install-face-detector (89 MB). Without it, edits draw as before, with
    each person's description and clothes, and the manifest names whose crop
    went.

  • mecha setup chat gives a machine with no model server a local chat
    model.
    It shows the model recommended for the machine's memory tier, or
    takes a GGUF you have; installs llama.cpp if there is none; installs and
    starts the router as a systemd user service on :8080; waits for the model
    to load; and offers to write the local provider from what the router reports.
    A router you set up by hand is left alone. Linux only.

  • mecha features enable installs the embeddings and OCR servers. On a
    Linux machine without them, enabling a feature that uses one fetches its
    pinned model, writes its launcher and the systemd user units that start it on
    its first request and stop it when idle, and starts it once to check it
    answers. A server already set up by hand is left alone.

  • mecha setup engine --upgrade moves to a newer llama.cpp — only if it
    measures no slower.
    It finds the newest release with a build for this
    machine (or --to <tag>), asks you to confirm that tag, checks each archive
    against the digest GitHub publishes for it, and measures it against the build
    the servers run with the same gate as --adopt. A win moves the servers to
    it and keeps the old build; --rollback goes back one build. Two builds stay
    on disk.

  • mecha setup engine says which llama.cpp each server runs, and --adopt
    moves them onto mecha's — only if it measures no slower.
    It runs each
    server's own launcher on a private port with the old engine and then the
    new, loading the model you have loaded, measuring generation and prefill and
    checking chat, embeddings and OCR, and records the result in
    ~/.mecha/sidecars/llama/ledger.jsonl. The router is stopped while it
    measures, so it asks first and declines if anything is running.
    --rollback puts the servers back on the llama.cpp you installed, which
    --adopt leaves in place.

  • mecha features enable installs the llama.cpp engine. On a machine
    without one, enabling a feature that runs something on it offers the
    official release for this machine — CUDA by the driver's version, Metal on
    Apple silicon, else CPU — checked by sha256, into
    ~/.mecha/sidecars/llama/<tag>/ behind a current link, with every
    library found beside it. A machine whose chat runs elsewhere is not offered
    the engine for a feature that runs nothing on it.

  • mecha features enable installs what the feature needs. It shows the
    plan, installs on one yes, and switches the feature on only after the
    install has passed its check. The first installer is layout's: a pinned
    uv (or one already on PATH), the Python 3.12 build it fetches, the
    hash-locked onnxruntime and numpy, and the pinned PP-DocLayoutV3 model, all
    under ~/.mecha/sidecars/layout/, where document extraction now looks
    first. Answering no writes nothing. --no-install writes the switch alone.
    Without a terminal, an enable that would install refuses and says so.
    Anything already on the machine is left alone.

  • mecha features plan <id> says what a feature would install. It
    lists every program the feature runs beside mecha — llama.cpp, the router,
    the embeddings and OCR servers, ComfyUI, the voice servers — and whether
    this machine already has each (a unit, a binary, a directory or a Docker
    image that shows it, which is then left alone). Then it lists every pinned
    model file: in the cache and matching, to download at its size, or kept by
    a provided program. It installs nothing and asks no server; --verify
    hashes model files placed by hand.

  • A voice that takes direction is told how to say each sentence. When
    the speech engine honours instructions (Breeze TTS 2), the worker asks
    the voice facade's new director for each sentence — one line on emotion,
    energy, pace and pitch, written by the model already loaded, with thinking
    off — and sends it with the words. The first sentence's direction starts
    from your words as the turn begins. Every direction is recorded in the
    conversation's transcript as a spoken_direction record, except in an
    incognito chat, where it is directed and nothing is kept. On a voice that
    does not take direction, nothing changes and no extra call is made.

  • A streaming voice is no longer told to keep it short. When the speech
    engine streams audio as it synthesises (Breeze lists "streams": true),
    the worker says so (X-Voice-TTS-Streams: 1) and a spoken turn opens with
    a block that keeps every voice rule but the length ones, and a persona's
    call note drops "short sentences, the first one short". Those rules were a
    latency control for an engine that speaks a sentence only once all of it is
    made; on Chatterbox the prompt is byte-for-byte what it was.

  • A Breeze TTS adapter. scripts/voice/breeze_server.py
    serves the same speech interface as the Chatterbox server, in front of Breeze TTS 2
    on a qwentts.cpp fork. It transcribes each voice clip once with Parakeet (an editable
    .txt beside the WAV), registers voices with the engine, speaks the default voice
    as the clip default.wav, passes delivery instructions through, and stretches when speed is
    not 1.0. Units for the engine and the adapter ship in scripts/voice/ and are installed
    by hand; docs/VOICE-BREEZE-DESIGN.md §5 says which gates the switch left open.

  • mecha features --probe adds up what your models would hold. Every
    model the features you have on would load — the chat model, embeddings,
    OCR, layout, image generation, speech to text, speech and turn detection —
    with what each costs, how it holds memory (resident, on demand, released
    on idle, per request) and on what evidence, summed against this machine's
    memory: one pool on unified memory, or the card and system memory
    separately with a separate GPU. A sum with an unmeasured figure in it is
    shown as unknown, never as zero, and what the figures leave out — the chat
    server's process memory, the router's prompt cache — is named. It reads
    /proc/meminfo and nvidia-smi and asks no server. The hardware page's
    Beside the chat model table is now generated from the same rows, which
    also pin each model's source (revision and sha256) for the installers to
    come. mecha features --json now warns about an unknown [features] key on
    stderr too, as the plain listing always did.

  • An idle image server gives its memory back. A new user timer
    (scripts/comfyui/install.sh) restarts ComfyUI once it has held a model
    for fifteen idle minutes, with nothing queued and nobody connected. That takes
    it from ~13.6 GB to ~1.1 GB with its port still up. The next picture loads
    the model again, ~15–22 s. mecha's own unload timer dies whenever
    mecha serve restarts, and on unified memory it only moved the weights
    into the server's process memory.

  • See and edit what a persona remembers. A persona's editor has a
    Memories tab: its conversations, what it knows about itself and about you,
    and anything waiting for your approval, each with the day it was said.
    Keep what is waiting, edit a fact's wording, pin, share a fact about you
    with everyone or a group, or forget something for good.

  • The uncensored Qwen3.6 model is about 40% faster. Its download lacks
    the multi-token-prediction head that lets production draft ahead;
    scripts/mtp-graft.py copies the head from production's file, and the
    router speculates with it (99.8 against 69.9 tok/s, one stream; the
    router's four slots are unmeasured). Without the grafted file the router
    serves the model as before and prints the command that builds it. If four
    slots turn out slower, removing the two SPEC lines from the preset in
    start-router.sh turns speculation off again.

  • The hardware page covers a separate GPU, and every model beside the
    chat model.
    Each memory tier now has two columns — unified memory, and a
    graphics card with system RAM beside it — and a new Beside the chat model
    table gives what embeddings, OCR, layout, image generation and the three
    voice models cost on the GB10, whether each holds its memory always, on
    demand or per request, and where every number comes from. Only measured
    cells say measured.

  • A persona's voice is picked in its settings. The settings form has a
    Voice field listing the voices the voice worker has, so voice = "…" no
    longer has to be typed into persona.toml. A save is checked against the
    list as it stands then; when the worker cannot be asked, the field says
    why and keeps the voice already set. voice_speed is still edited as text.

  • Voice and persona settings in the config file. A new [voice]
    table holds the speech-to-text address dictation uses (stt_url, until
    now fixed in the code), the voice worker's address and the voice facade's
    port (until now only mecha serve flags, which still override them for
    one run), and voices_dir. A new [personas] table sets
    crisis_cooldown_minutes: after a crisis pause, how long a further crisis
    message in the same chat does not pause again (15 by default). Both are
    read from your global config only. [web] voices_dir has moved to
    [voice] voices_dir; the old key still works for one release. The
    speech-to-text and voice worker addresses must be on this machine, in
    [voice] or in mecha serve --offer-target: a voice worker on another
    host is now refused at start rather than reached.

  • Type during a call. A call, with the assistant or a persona, has a text
    box under its transcript. A typed line is a turn like a spoken one, and the
    answer is spoken in the call's voice. The microphone pauses while the box
    has focus and comes back as it was; the mute button stays yours.

  • Personas can look things up in their own memory. Two new persona
    tools, offered whenever a persona's memory is on: memory_search finds
    what it remembers when it needs something you did not just mention, and
    memory_read opens a remembered conversation in full, so it can quote what
    was actually said rather than the summary. Conversations in its memory now
    show a short id in brackets for that. Reading a past conversation that took
    in outside content marks the current chat the same way. A persona set to
    answer only from its files still remembers, but reads a past conversation
    as what you and it said: whatever a tool brought back, such as a web
    search, is left out. A long conversation keeps its ending when cut.

  • Listen to a reply. Under each finished reply, beside Copy and Download,
    Listen reads it aloud: a persona's in its own voice, the assistant's in the
    voice you chose in Settings → Voice. Code, links and formatting are not read
    out; a code block is said to be there. It starts after the first sentence
    and stops when tapped again.

  • Library → Voices. Every voice the voice server can speak is listed in
    the library. Tap one to hear a sentence spoken in it, record or upload (WAV)
    a new one, delete a clone, and see which personas speak in each. Recording
    and deleting moved here from Settings → Voice, which keeps the assistant's
    own voice and rate.

  • Make a persona from the main chat. Ask for one ("help me make a
    persona who…") and the assistant drafts who they are and what they want,
    and stages it with a new persona_propose tool. It waits on the Personas
    page under Waiting for you: read it there, then Approve or Reject.
    Approval accepts exactly the text you were shown — if the chat revises it
    meanwhile, you are asked to read it again. Ask the chat for changes and it
    revises its proposal until you approve; after that only you edit it. If
    it links a portrait that is also still waiting, Approve both takes
    them together. A persona proposed in an incognito chat starts hidden
    behind the library lock. The chat can set the name, display name,
    relationships, identity, motivation, portrait and voice; tools, files,
    memory, safety switches and the lock stay yours. Once you edit a waiting
    proposal yourself, it is yours, and the chat can no longer change it.

  • Download a generated picture. Every picture a chat draws — in the
    assistant's chat or a persona's — has a Download button beside Edit,
    which saves the file under its own name. It works in incognito and locked
    persona chats too, and leaves no picture address in the browser's history.

  • Personas recall during a chat, not only at its start. Each message
    you send after the first reply is searched against what the persona
    remembers — by your words and by meaning, recent first — and the few
    things it calls up that the chat has not already seen ride along with it:
    an older conversation, a fact that did not fit at the start. The nightly
    memory pass now also prepares memories for searching by meaning; without
    the embeddings server, recall works by words. Forgetting a memory removes
    it from the search index too.

  • Copy and Download on every chat reply. Under each finished reply, in
    the assistant's chat and a persona's, Copy puts the reply on the
    clipboard as written — its Markdown, not the rendered page — and Download
    saves it as a .md file named for who said it and when — in an incognito
    chat too, since the file is made in your browser and the server keeps no
    trace of it. Every code block in a reply has its own Copy.

  • Call a persona. A persona chat has a call button beside send, where
    calls are switched on. The persona answers in its own voice (its profile's
    voice, which the voice server must list), and what is said lands in the
    same chat. A locked persona can be called only while it is unlocked, and
    locking it again ends the call. A crisis message on a call is answered
    aloud with the same plain words the chat shows. Call minutes join turns on
    the persona's usage meters. The voice worker must be restarted on this
    version before a persona with a voice profile can be called; until then
    such a call is refused, naming the reason.

  • Replies read as formatted text. In the assistant's chat and in persona
    chats, a reply's Markdown (headings, bold, lists, code) is rendered rather
    than shown as ## and **. Double-click a reply to see it as written, and
    again to go back. Rendering is safe for words a third party wrote: no raw
    HTML, links only to web and mail addresses, no images fetched.

  • A persona's page is easier to work with. Drop files onto its Files
    tiles; a file you add shows as uploading… at once. Click a file to
    download it, or to read its text once it has been read. Earlier chats are
    listed by what they were about (the persona's memory summary, the goal, or
    how you opened it) with the day and time together. The goal box is now a
    Set a goal for this chat link. In a chat, your message no longer shows
    the goal framing sent ahead of it, and repeated calls to one tool show as
    one row (file_read ×6).

  • Personas remember you in the next chat. A new chat with a persona
    starts with what it remembers: your about-me notes, what it knows about you
    (and what you shared with it), its own facts, and its last few
    conversations, each switch on its settings page honoured. Memory that came
    from something read from outside — a search, a file — marks the chat as
    having outside content, as reading it again would; ordinary memory does
    not. Searching memory during a chat comes next.

  • A persona's picture can be framed. Tap the picture on a persona's page
    to open it in the circle: drag it into place and zoom, then Save; Reset puts
    it back. A persona that gets a new portrait — made with one, or given one in
    its settings — opens it there straight away. Until you frame it, a tall
    portrait shows its top — the face — rather than its middle.

  • Hiding a persona behind the library lock is a switch in its settings,
    at the top of the Settings tab, rather than an item in a ⋯ menu. The menu
    is gone.

  • Save a persona's reply to its files. Under each of a persona's replies
    there is a Save to files link: a study guide, quiz or glossary it wrote
    when you asked is saved as a Markdown file in its own folder, there next
    time (and searchable), and movable to a group's folder to share. Only the
    persona's own reply is saved, never text it did not write. The teacher
    starter now asks before revealing quiz answers (new installs; an installed
    copy is yours and is not changed).

  • Personas start remembering. mecha persona memory write reads each
    persona's chats and records an episode and facts per stretch of
    conversation, in the persona's own memory. The nightly runs it. Each chat
    is written on this machine by the model it ran on, and only while that model
    is loaded — it never swaps out the one in use. Chats changed in the last 15
    minutes, and test chats, are left alone, and each turn is read once. A stretch after the chat read anything from
    outside — a search, a file — is kept apart: what it produced waits for
    your approval (mecha persona memory approve), and it can never change or
    withdraw what the persona already knew. Nothing yet brings memories back
    into a chat; that is the next step.

  • The library and personas lock themselves again. After 15 minutes with
    no one touching the page, the Library and Personas tabs relock on their
    own, and the unlock ends on the server too. Change the span under
    Settings → Lock or with mecha imagelib set-autolock <minutes> (1 to
    240). Leaving either tab also ends its unlock.

  • A persona searches its files. When a persona's files are too long to
    read whole, it finds the passages that answer a question with a new
    file_search tool, by meaning (through the :8081 embeddings server,
    [documents] embed_url) and by words, and reads around them with
    file_read. Files are indexed in the background once they are read; a
    quote taken from a search result is checked like any other.

  • A persona's citations are checked. When a persona quotes one of its
    files as [file, p. N: "…"], mecha looks the quote up in what that chat
    actually read and tags it: quoted, on p. N (the quote is real but on
    another page), not in the file, no such file, file not read (one of
    its files it had not read yet), can't check (a script without spaces),
    or too short to check.
    Tap a found citation to see the page as the chat read it, with the passage
    marked. "Quoted" means the words are there, not that they support what
    was said.

  • An experiment environment can say which features its tasks need.
    requires = ["graph", "search"] in its environment.toml (inherited by
    any environment that extends it) makes mecha exp run refuse to start
    when a trial home has one of them switched off, naming it, rather than
    scoring the model on tasks it could not attempt. It checks the switches,
    not that a feature switched on is set up. A name no experiment environment
    can switch on, such as mail, is refused as soon as the experiment loads,
    with a pointer to fixture servers, or to an arm's levers_on for
    messages. Each run's session record now also notes which
    features were switched on.

  • A persona reads its files. Each persona has a Files list on its page:
    add a paper, notes or an image there (or drop them into its files/
    folder), and every new chat with it carries them. If the whole collection
    fits in about a quarter of the context window, it rides in full in the
    chat's first turn; otherwise the chat gets the list and reads pages with a
    new file_read tool. A persona also reads its groups' and everyone's
    files/, named @group/… and @all/…. Files are processed once on upload,
    one at a time, and the list says which are ready, and why one cannot be
    read. A chat never waits on a document still being processed: its first
    turn says the file is on its way, and file_read reads it later. A
    file's words are treated as outside
    content, so a chat that carried them is marked untrusted and private. With
    [security] block_sends_after_private on, a persona with files therefore
    stops web_search in its chats. answers = "files" keeps file_read,
    since that is what reading the files means.

  • mecha setup covers every optional feature. It has a step for each —
    the web app, Slack, mail, docs, the knowledge graph, web search, PDF
    extraction, image generation, personas, voice, incognito chat, the front
    door and messages — read from the same registry as mecha features, with a
    feature's dependency offered first. A feature not switched on is offered
    with mecha features enable … and can be declined; one you switched off in
    [features] counts as answered; one switched on but not working is shown
    as wrong, with the next command or the edit it needs. Mail, docs and the
    graph now count as set up only with an [[mcp]] entry for their server —
    an installed binary alone used to read as done. mecha setup <feature>
    sets up one, and mecha setup --minimal declines every optional step in
    one pass without touching your config. A step you declined before keeps
    its answer, and naming it — mecha setup mail — offers it again; the closing
    note says how to take back each kind of "no" (--undecline for one given in
    setup, mecha features enable for a switch you set to false).

  • Personas have a memory store. Each persona keeps its own memory.db
    (episodes, its own facts, and what it learned or inferred about you), and
    facts you choose to share with every persona or a group go in shared.db.
    mecha persona memory show|export|approve|correct|pin|unpin|forget|share|shared|unshare
    is how you curate it. Every record names the chat it came from, so
    forget --chat removes everything remembered from that chat from both
    files, and deleted text is overwritten on disk. Nothing writes memories or
    recalls them into a chat yet — those come next.

  • Slack, personas, voice, incognito, the front door and messages follow
    their switches too
    , the same way the rest do: off, their web pages answer
    feature_off and mecha slack, persona, msg, frontdoor, polls and
    voice-serve refuse with one sentence and the command that turns the
    feature on. The front door's publishing server is no longer started with
    frontdoor off, and mecha serve does not mount its voice facade with
    voice calls off. Reading what is there stays open (slack status,
    threads, persona list, show), and so do slack auth and slack unlink. mecha msg now refuses when messages is off, reads included —
    it used to work either way.

  • A feature that is off refuses the same way everywhere. With mail, the
    knowledge graph (and its task board), PDF extraction or image generation
    switched off in [features], the web app's routes for them answer 404
    with {"error": "feature_off", "feature": …, "why": …, "fix": …} — only to
    the owner; anyone else still gets 403 and learns nothing — and their
    commands (mecha mail, tasks, kg, review except queues, document extract, and the imagelib commands that change an entry) refuse with one
    sentence, such as "Mail and calendar is off (turned off in [features]) —
    mecha features enable mail"
    . They used to fail in five different ways,
    and the graph's review queue, mecha review accept and the web's entity
    create and merge still wrote the graph with graph = false. A missing
    graph tool now names the switch when that is why, not [[mcp]]. mecha batch prints the upgrade line, as run does. On Home, a review queue
    whose feature is off shows its count and the command, and no longer opens
    a page that cannot load. The switches are read on every request and
    every command, so enabling or disabling a feature takes effect at once, on
    the web too; only the web chat's tools wait for mecha serve to restart
    (Settings → Features lists the switches waiting on one).

  • Eval cases can attach pictures. "attach": [...] in a case puts
    images on its first turn as pixels, exactly as a web-chat upload does, so
    a case can measure what a model does with a picture it can already see.
    The chat, the persona chat and eval now share one implementation of that
    (image::attached_images). eval/image-read/ is the first set: 19 cases
    over photographed pages, tables, receipts, screenshots and pictures with no
    text. Measured on the resident vision model, it never chose OCR for an
    attached picture, even when asked for a spreadsheet or a transcript, and a
    description telling it to did not change that. Its answers were all right,
    and on one hard page it transcribed as well as the OCR model did. So
    pictures stay read from pixels; document_read is there when asked for.

  • The web app shows only what is switched on. Its tabs, Home's Mail and
    Tasks cards, the voice-call button, every dictation mic, the incognito
    buttons and Review's Graph queue and Front door tabs follow [features],
    read afresh on each page load from a new GET /api/features (the same rows
    as mecha features --json). A feature that is switched on but not ready
    keeps its tab, marked, with what is missing above it; a link to a hidden
    page lands on Home with one line saying so. Settings → Features lists
    every feature, off ones included, with the command that turns it on, and
    says which switches mecha serve has not picked up yet. A Home queue with
    anything waiting stays even when its feature is off. No route refuses
    anything yet.

  • Read a photo or screenshot of a page. document_read and
    mecha document extract now take PNG, JPEG, WebP and GIF as well as PDF.
    A picture is read as one page by the local OCR model, through the same
    layout stage, cache and caps as a scanned PDF page. Phone photos are
    turned upright from their rotation tag first: on an upside-down test page,
    skipping that put the heading last and misread the paragraph as a table.
    Transparent screenshots are read on white. HEIC photos and TIFF scans are
    refused with what to do instead. Personas that have document_read get
    this too.

  • A persona draws itself (PERSONA-DESIGN §8.6). In a persona chat,
    "who": "self", or the persona's own name, is its linked library
    character. On a persona with no character, self is an expected failure
    that says to describe the persona instead. It used to be refused for
    naming a library character without cast, and the local model resent the
    same call: 82 of 87 calls in the first live chat.

  • "No picture was made in this reply." The persona page says it under a
    turn whose image_generate calls all failed, read off the tool rows, so a
    reply saying "here you go" over nothing is not the last word.

  • Every optional feature has a switch: [features]. The global
    config.toml gains a [features] table with one true/false per
    feature — web, Slack, mail, docs, the graph, search, PDF extraction, image
    generation, personas, voice, incognito, the front door and messages.
    mecha features enable <id> and disable <id> edit it in place, keeping
    your comments; mecha config init writes it with every line commented —
    listed and off, but not answered, so mecha setup asks about each. (A
    config written by an earlier config init, with every line = false, reads
    each as a no: comment out or delete the lines you want to be asked about.) An install
    from before the table has every switch unanswered, so mecha features marks
    what you have set up as "not enabled, but set up here", a session or service
    prints one line naming them when it starts, and mecha setup offers each.
    A project's mecha.toml cannot set the table, and an experiment environment
    may only switch features off (and the front door on).

  • Persona chats show their pictures, with the same Edit button. A picture
    a persona draws now appears under its row in the Personas tab, as in the
    main chat, and Edit opens the same paint-a-region modal. A locked persona's
    pictures stay behind the library lock, and have no link to open them in a
    new tab.

  • Drop or attach files in a persona chat. Drag files onto the Personas
    tab, or use the paperclip, just as in the main chat. Files land in the
    chat's own inbox/ and are named in your message. A picture is also shown
    to the persona when its model can see images, and the chat is marked as
    holding something private from that turn on — including a turn the crisis
    pause held, and after a restart.

  • Personas can read PDFs. Add "document_read" to a persona's
    [tools] allow and it can read a PDF dropped into its chat. It gets the
    PDF's own text, with OCR for scanned pages, as in the main chat. It is off
    until you list it. A persona set to answers = "files" never gets it,
    because a document's words are third-party content. A persona with both
    document_read and web_search could be steered by a hostile PDF into
    searching for something; drop web_search for a persona that reads files
    you did not write.

  • The charter editor keeps your comments. Saving the charter from the
    web page now changes only what you changed: comments above and among the
    lines stay, a line you drag takes its comments with it (a comment right
    above the first line reads as the file's header and stays at the top),
    and a setpoint you
    did not touch keeps its spelling. A charter with comments among its lines
    can be edited as a list, not only as TOML. A save made from a page that
    read an older charter is refused rather than written over.

  • Paint the part of a picture to change. The web chat's Edit button now
    opens a modal: paint or draw a box over what should change, say what to
    do, send. Only the painted area is redrawn, blended over a narrow edge
    around it. Everything else comes back exactly as it was, pixel for pixel,
    so "make her dress green" no longer nudges the rest of the scene. A large
    photo is edited at the model's working size, as any edit of it is. With
    nothing painted, the whole picture is edited, as before. Local swaps,
    recolours and details land reliably this way. To move someone or change a
    pose, use a plain edit or redraw from the library.

  • mecha features lists which optional parts of mecha are on. Web,
    Slack, mail, docs, the graph, search, PDF extraction, image generation,
    personas, voice, incognito, the front door and messages, each marked on,
    off, blocked (waiting on something else that is off), unready or unknown,
    with the command that turns on each one that is off. It reads the config
    and the disk only and wakes no server. --json for scripts. The first step
    of making installs modular (docs/FEATURES-DESIGN.md).

  • A cleaner Personas tab. Personas are listed like contacts: avatar,
    name and relationship, with New in the header. A persona's page leads
    with who they are and one Start a chat button; Edit is a pencil, and
    hiding behind the library lock moves into a menu. Earlier chats show the
    goal they were opened with. In a chat, the header shows just the name and
    the AI tag, with the model chip (the same picker as the main chat); the
    send button sits inside the message box, and the back arrow ends the chat
    (the Done button is gone). While a reply is on its way, a line says the
    persona is typing, or what it is doing and for how long, such as
    "drawing a picture… 1:24". A tool call the persona retried reads as
    retried, not failed. The support-resources link appears only after a
    crisis warning in that chat, and the banner at the top of each chat is
    gone.

  • Persona files edit as forms. A persona's Edit screen is now a form on
    every tab. Settings are switches, choices and name chips: relationship,
    groups, portrait, tools, the safety switches and memory. A change is set
    in place in persona.toml, and every comment you wrote stays. Who they are
    and what they want edit as a title and sections, each with an optional
    note to yourself, saved in one tidy layout. ## Core cannot be removed.
    "Edit as text" is still there on each tab. Switches the harness does not
    use yet say so. Typed --> no longer shows as an arrow, and a comment
    typed on a phone keeps its dashes.

  • Make and edit personas on the web. The Personas tab has a New persona
    form: name, relationship templates, a library portrait and groups. New
    kinds of relationship (how someone in it behaves) and new groups can be
    added from the same form. Each
    persona has an Edit screen for who they are, what they want, and its
    settings, saved exactly as you type them, comments included. A settings
    file that would not load is refused and left as it was, and an edit made
    elsewhere in the meantime is never overwritten. Lock and unlock from the
    same screen.

  • Personas: characters you write and talk to, in their own tab. A new
    Personas tab on the web page lists the personas you made with mecha persona, each with its library portrait. Choose one to start a chat, with
    an optional goal, or to pick up an earlier chat. Persona chats are kept
    apart from your assistant. They cannot see your mail, calendar, graph or
    other chats. Their transcripts live under the persona's own folder, where
    nothing that learns from your sessions looks. A persona gets only the tools
    it asked for that are safe for it: web search (fixed destinations only),
    image generation and viewing, and the image library. A safety layer runs in
    every persona chat:

    • a line saying it is an AI;
    • a crisis check on what you type, which pauses the persona and shows 988
      and the Crisis Text Line;
    • the persona's Core handed back to it on a cadence;
    • usage meters.

    Each can be switched off per persona in its persona.toml, and a switch
    reaches chats already open. Behind the keywords, a model check screens
    each message you send, including one sent while the persona is answering,
    and pauses the persona if it finds a concern the keywords missed. When
    that check cannot answer, the page says crisis detection is on keywords
    only until it can.

  • OCR reads tables whole. With the layout stage installed
    (scripts/layout/install.sh), an OCR page is read region by region: a
    layout model (PP-DocLayoutV3, CPU, sandboxed like the PDF parser) finds
    its tables, formulas, headings and paragraphs, and each is read with the
    prompt the OCR model was trained for — tables come back as Markdown tables
    with every column, headings are marked, and each region's box is kept for
    citations. Without it, pages are read whole and the transcript says so.

  • Read PDFs: document_read and mecha document extract. Each page
    comes back twice, labelled: the PDF's own text layer (exact — what a quote
    is checked against) and, for scanned pages or when asked, a transcript from
    a local OCR model (PaddleOCR-VL 1.6) with equations as LaTeX. The PDF parser
    runs sandboxed, results are cached by the file's hash so a page is never
    read twice, and the OCR server starts when a page needs it and stops after
    ten idle minutes. Configure with a [documents] table in
    ~/.mecha/config.toml (see mecha config init); install the server with
    scripts/llama/install.sh. Tables read by whole-page OCR are not reliable
    — install the layout stage (above), or use the text layer for numbers.

  • Personas, step 1: the store and mecha persona. A persona is a
    character you write and talk to, kept apart from the assistant. It lives in
    a folder under ~/.mecha/personas/: persona.toml holds its settings,
    identity.md who it is, and motivation.md what it wants. mecha persona new makes one, optionally starting from a relationship template. Ten
    starter templates are copied into relationships/ once, for you to edit
    freely. edit opens a file in $EDITOR, and each saved change becomes a
    new version. lock hides a persona while browsing, using the image
    library's lock. group add declares a group whose members share an
    about-me and a files/ folder. A broken link to a template, group, voice or
    library character is reported by name. Chatting with a persona comes in the
    next step.

  • mecha sessions mark <id> experiment withdraws a session you ran as a
    model probe from everything that learns from your sessions: the run
    corpus, reflect, distill, learn, and its appraisal and scores. The
    transcript is untouched, and mecha sessions unmark undoes it. Only you
    can mark, from your own terminal; a run's shell is refused. The verb names
    the session's graph episode, if it was distilled, for you to retract there.

  • mecha distill --backfill-appraisals appraises, after the fact, the
    sessions distilled before appraisals existed whose clean steer or denial
    was waiting only on an appraisal to be compared. There were 9 on the live
    store. Nothing is pushed to the graph, and the rows written predict
    nothing, since the outcome was already known. --dry-run lists them.

  • The lesson-source comparison states its verdict. mecha learn --compare-sources and sessions appraise print R25's gate for folding the
    reflector in (2a-4) and feeding appraisal lessons to learn (2e-2), decided
    on the paired verdicts. Under 10 decided comparisons the result is a pilot.
    From 10 up it is "no worse" while the appraisal trails the reflector by at
    most 2 discordant pairs, and "worse" past that. There is no verdict at all
    while any line of the stores behind it is unreadable, since every count is
    then a floor. The counts behind the verdict are printed beside it, and
    --json carries it as gate.

  • mecha rules show <id> finds a rule that consolidation dropped. Learning
    rewrites its rule set and leaves some rules out; they are not retired, so the
    learner is never told they were harmful. Their text lives on in the proposal
    that dropped them. show now answers from there: which proposal dropped the
    rule, when, its last text, and its validation record. It says "never live"
    for a rule only ever proposed. Read-only.

  • Draft forecasts. When a run stages a message, mecha now predicts what
    you will do with it: send it as written, edit it, reject it, or leave it
    past the outbox's patience. The prediction is your most common act on
    similar earlier drafts. It is kept out of every review surface and every
    prompt, so it cannot sway your verdict, and sessions appraise reports
    how the predictions fare. Only acts stamped as yours count.

  • Add and edit characters and styles from the Library tab. Add
    character
    takes a portrait from your device, a name and a description.
    Add style takes a name and its text. Edit changes an approved
    entry's description or portrait, keeping the earlier version for pictures
    already made from it. A portrait is resized and stripped of its photo
    metadata before it leaves the device.

  • People who aren't in your image library can share a scene with those who
    are.
    Ask for "Maya and John at a diner, with a waiter pouring coffee" and
    the waiter is drawn as a new person, counted with your characters, so he
    takes part in the scene instead of being pushed to the background. A
    person the scene only mentions in passing is no longer erased either:
    your characters are each drawn exactly once, without a fixed total that
    left no room for anyone else.

  • Archive or delete a conversation from the web chat's drawer. Each row
    has a ⋯ control. Archive hides a conversation and keeps the record
    whole — learning, appraisal and the graph still read it — under a new
    archived section; opening one (or restore) puts it back in the list. Delete
    removes the transcript and everything derived from it: its workspace,
    staged drafts and waiting questions, the reflections and learned rules
    drawn from it, appraisals, and its knowledge-graph episode. A delete that
    could not reach a store says so and can be run again to finish. The same
    from the command line: mecha sessions archive|unarchive|delete <id>.
    Deleting a distilled conversation needs the mecha-graph release with
    redact --source.

  • The image library in the web app. A Library tab shows your
    characters and styles, with a Waiting pane for ones the model proposed:
    read the text, then approve or reject. Save to library under any picture
    in chat makes it a recurring character. Locking hides a character while
    browsing (it stays usable in chats); the lock button shows locked entries
    again — a plain toggle, or password-protected once you run
    mecha imagelib set-lock-password. Waiting candidates also appear among
    Home's review cards. Rebuild the page and restart mecha serve to use it.

  • An image library of recurring characters and styles. Add a character
    once — a portrait and a short description — and name it in
    image_generate's new cast field, with what each person is wearing and
    doing; the library supplies how they look, so the same people come back
    across images. style applies a stored style. The model can propose an
    entry (image_library_propose), which waits for you: mecha imagelib list --all, approve, reject, add-character, add-style, lock. Every
    generated image now also gets a manifest beside it (images/<name>.json)
    recording how it was made. Install the new binary; nothing to configure.

  • Voice calls in incognito chats. An incognito chat now has the call
    button, and nothing of the call is kept. While such a call is live
    the voice worker silences pipecat's logging, which otherwise writes both
    sides of every call to the journal, and withholds the words from its own
    lines. mecha serve asks the worker before it forwards such a call, so a
    worker that has not been restarted is never handed one, and the page goes
    on only if the answer confirms it. Ending the chat hangs up the call.
    Restart the voice worker and mecha serve, and rebuild the page, to use
    it.

Changed

  • The picture tool's results report facts only. A result gives the
    picture's path, size, time and seed, and for an edit whether its layout
    barely changed. The suggestions each result used to carry about what to
    try next now appear once, in the tool's description, so they no longer
    pile up in a chat's history (docs/PERSONA-CONTEXT-DESIGN.md §5.2).

  • Picture edits are described in parts, and the tool writes the edit
    model's instruction.
    An edit now names the one change (and, if it
    matters, what stays, what a face does, or where the camera goes), never a
    description of the whole scene, which the edit model reads as the picture
    it already has. Persona edits had been coming back unchanged; replayed, a
    scene description made the asked-for change 3 times in 8 and an
    instruction 8 times in 8. An edit sent as a free description is refused
    with what to send instead. From the edit panel, the owner's own words are
    the change (docs/PERSONA-CONTEXT-DESIGN.md §5.5).

  • A persona's harness notes last one run and are no longer stored in the
    chat.
    A recall, the reminder of who it is, and the call, variety and edit
    notes used to be written into the owner's message, where they stayed and
    were re-sent on every later turn. At one measured moment
    they were 39% of what the model read, against the owner's 3.5%. They now
    ride the request they are for and nothing after it (RunContext::notes),
    and the session records them separately for audit. Chats recorded before
    have their stored notes left off what is sent; such a chat's first reply
    after the change re-reads its history once. The call note now goes on
    every spoken turn, and tells only a persona that can make pictures that
    its pictures reach the owner's screen
    (docs/PERSONA-CONTEXT-DESIGN.md §5.1, §5.6). What the persona remembers at
    the start of a chat is stored once in the chat's first turn and kept there,
    as before: sent as a note it added about a second to every reply and made
    the persona skip pictures it was asked for.

  • Pictures take about half as long: the image model is now the int8 file.
    [image] diffusion_model defaults to qwen_image_2.1_int8_convrot.safetensors
    in place of the Q4 GGUF. On the DGX Spark a picture takes about 28 s instead
    of 64, and an edit about 37 s instead of 80, with the same pictures for the
    same seed. It loads through ComfyUI's own loader, so the ComfyUI-GGUF node is
    no longer needed for the default; a .gguf file still works through it.
    Put the file in ComfyUI's models/diffusion_models/
    (Comfy-Org/Qwen-Image-2.1) before upgrading, or set diffusion_model
    back to the GGUF. It needs about 0.7 GB more at its peak, so
    min_available_mb defaults to 20480 (was 19456).

  • A large photo is scaled down before an edit. A reference over 4
    megapixels — every phone photo — goes to the image server scaled to 4 Mpx,
    turned upright, without its metadata. The model works at about 1 Mpx, so
    nothing is lost, and the server no longer spends ~2 s an edit decoding the
    full photo. The photo in the chat is untouched.

  • The memory figures count speech as Breeze, the new default voice.
    mecha features --probe and the hardware page now use Breeze TTS 2 (Q6_K,
    qwentts.cpp): 4.1 GiB at its peak while speaking, read on the GB10, where
    Chatterbox was 7.8 GiB. The machine-wide sums fall by the difference,
    about 4 GiB.

  • Breeze TTS 2 is the default voice. The voice worker's MECHA_VOICE_TTS
    now defaults to the Breeze adapter on :8887 (engine on :8886) instead of
    Chatterbox on :8881, which stays available as the rollback by setting the
    variable back. The update skill says when the adapter needs a restart.

  • The model launchers find the Hugging Face cache the way hf does.
    The router, the embeddings and OCR servers and the other start scripts
    looked only at HF_HUB, then ~/.cache/huggingface/hub; they now also
    honour HF_HUB_CACHE, HF_HOME and XDG_CACHE_HOME, in the order hf
    and mecha's downloader use,
    so a model hf put under HF_HOME is no longer reported missing. The
    layout installer tells hf the same directory. With none of them set,
    nothing changes.

  • A persona names a library voice directly. voice = "ada" in
    persona.toml is a voice from Library → Voices, with an optional
    voice_speed (0.5–2.0). The voices/<name>/profile.toml profiles are
    gone; nothing used them yet.

  • A persona's page is quieter. It no longer states its crisis-detection
    setting, and its files are small tiles with a compact add tile, instead of
    full-width rows that read like a second "Start a chat".

  • An experiment's condition hash now includes the features a trial runs
    with.
    Turning search on or off between two runs of an experiment used
    to leave every trial's hash the same, so the two runs could be paired as
    one condition. Every new trial's hash changes once with this release, so
    trials planned from now on do not pair with ones planned before it; a
    resumed experiment keeps the hashes of the trials it already finished.

  • The character library follows image generation. It is on whenever
    image is — its page, its routes, mecha imagelib — and [tools]
    disabling image_library or image_library_propose now only keeps those
    tools from the model, as [tools] does for every tool, instead of taking
    the Library page with it. mecha features says which library tools the
    model is missing. The library's lock password and its unlock, relock and
    portrait routes stay open whatever the switches say, because Personas uses
    them.

  • mecha features reads a switched-on feature with missing settings as
    unready, not off.
    image = true with no [image] table, or mail with no
    [[mcp]] entry, is something you said yes to, and now reads unready
    with the fix — and no longer hides the parts under it, which read unready
    beside it rather than on. A part turned off by its own setting
    ([documents] ocr = false) still reads off. A blocked row now prints the
    command that unblocks it, and --json rows carry shown and next. The
    start-up line for an install from before [features] can now name a
    feature that is set up but not yet usable, with the reason beside it —
    mecha features enable documents for a [documents] table whose
    document_read is turned off in [tools], or mecha features enable mail
    for a mail [[mcp]] entry whose mecha-mail is not installed. The switch
    alone will not make those work; the reason says what will.

  • A feature whose switch is not on is off. Web search, image generation,
    PDF extraction and the mail, docs and graph servers register or
    start only when their [features] switch is true, and mecha serve
    refuses to start without web = true. Before upgrading an existing
    install, answer the switches:
    run mecha setup, or the one
    mecha features enable … line a session prints when it starts — it names
    everything this install had set up. An MCP server that belongs to no
    feature starts as before; the graph server stays off for distill,
    gossip, vet and corroborate too. Slack, personas, voice, incognito
    and the front door (its queue and publishing) keep working for now whatever their switch
    says, and the start-up line tells them apart. Experiment trials keep their
    graph: it is on when the environment declares its own graph server or the
    manifest brings yours in with live_servers, unless the environment says
    false; search follows your own switch.

  • The learning store no longer uses git. ~/.mecha/learning/ is plain
    files: opening it no longer runs git init or writes a .gitignore, and a
    pass no longer commits. Git history kept every deleted reflection's text,
    which a chat deleted with all its traces must not leave behind. Each pass
    now appends one line to passes.jsonl — when it ran and what it counted,
    never content — beside runs.jsonl and each rule's sources and
    retirement fields, which already carried the lineage anything reads; the
    undo for a bad rule is mecha rules retire, per rule. An existing .git
    in the store is left where it is, unused; removing it is the owner's call.

  • The local model's prompt cache is 16 GiB, not 32 (-cram, both launch
    scripts). It fills over hours and never shrinks while a model stays loaded,
    and a full 32 GiB beside the model's own 43 GB left image generation out of
    memory on the shared pool. 16 GiB still holds 2.9 full 262k slots (5,632 MiB
    each), where the 8 GiB default, which thrashed, held one. Restart the router
    to apply it; MECHA_LLAMA_CRAM still overrides.

  • The web home is counts and doors. Four large cards for what is yours —
    mail that needs you, outbox drafts, questions a run is paused on, open
    tasks — then one small card per review queue, and a line each for
    follow-through and health. Every card opens its tab; nothing a tab already
    shows is repeated. The Today list of workflows, which is what made the page
    unusable, moves to the task board as its own view (#tasks/workflows),
    keeping every verb and Reopen for finished ones; home's Follow-through line
    opens it, and the Questions card opens the board's waiting view, where a
    paused run's question is answered. Tasks' views now follow the route, so
    Back returns to the last one. A count that could not be read is a dash,
    never a zero.

  • An incognito chat's model chip opens the picker too. Every model it
    lists runs on this machine, since the chip reads only routers a local,
    loopback follow_loaded entry names, and the menu says so. Incognito's
    local-only guarantee stays with its own provider and its per-turn check.
    The owner's amendment to INCOGNITO-DESIGN.md §6.1 (2026-09-28).

Fixed

  • Painting a region on a phone photo taken upright now edits it. A phone
    stores such a photo sideways with a tag saying so; the edit read it as
    stored, found it the other shape from the region painted over it, and
    refused. The near-copy notice read it the same way and could miss a
    copy. Both now read a photo upright, as the page shows it.

  • Listen no longer goes silent after the first sentence. A reply read
    aloud was spoken as its first sentence, then a ~400-character piece that
    could only play once it had all been made — about 8 s of silence on an
    idle machine and 16 s while a chat was generating. Each piece now streams
    from the voice worker through serve to the page, which plays it as it
    arrives and fetches the next piece while the last is still playing: speech
    starts about 0.3 s after the tap and runs without gaps. A voice worker that
    predates streaming still answers whole pieces.

  • Calls from Chrome buffer the microphone again. Chrome now has
    RTCRtpScriptTransform, and on a plain connection it hands the transform no
    audio frames, so every Chrome call declared the buffered uplink and fell back
    to the direct path ("the buffered microphone path failed"). The call page now
    creates its connection with encodedInsertableStreams in Chromium and pipes
    incoming audio through, which Chromium requires once that flag is on.

  • A persona chat whose model changed partway through is still
    remembered.
    If the router switched a chat to another model mid-way, the
    overnight memory writer kept waiting for the model the chat started on,
    possibly forever. A persona chat now records each switch, and its memories
    are written with the model it last ran on.

  • The ComfyUI idle reset reads only what it needs, and fails when it cannot
    see free memory.
    Its two journal checks now ask for the newest matching
    line (journalctl -g … -n 1) instead of reading the whole run's journal every
    minute, and tell "no match" from "unreadable" by what journalctl says on
    stderr. An unreadable MemFree fails the unit, where it used to be read as
    zero and answered with /free and a clean exit.

  • A picture asked for while the image server restarts waits for it. The
    first request of a job now waits for a server that is not answering yet:
    up to 90 seconds when this process has reached it before (it is
    restarting), 45 when it never has. A cancel stops the wait at once. Before,
    it failed straight away with "Is the image server running?", and a
    genuinely stopped server is now reported after that wait.

  • The image tool's memory check matches what a generation costs. It now
    asks the image server what it holds first. A server that has loaded
    nothing (just restarted, or unreadable) needs the full min_available_mb,
    now 19 GB, up from 16. A generation from an idle server needs ~18.5 GB above
    its idle footprint, and the old figure counted only the GPU side. A server
    that has already loaded the model needs ~7 GB less (12 GB at the default),
    so a second picture soon after the first is no longer refused for memory
    it would not use, and a raised min_available_mb keeps its margin.

  • A persona's memories are dated by when they were said. Everything a
    persona remembered was dated by the night it was written, so something you
    mentioned on Tuesday read as Friday's news. Memories now carry the day of
    the conversation they came from, in your timezone, and "recent" means
    recently said.

  • A persona no longer sends the same reply again when a turn adds
    little.
    Late in a long chat, a short owner message ("mm") could bring
    back an earlier reply word for word. Persona chats now send no fixed
    seed — the provider's pinned seed restarted the sampler at the same
    draws every turn — and leave earlier replies' reasoning out of what goes
    back to the model, which it had been re-reading and re-sending (a turn
    that called a tool keeps its reasoning, without which the model learns to
    call tools without thinking). Replayed
    on the turns that copied, copies went from 4 of 4 to 0 of 8 with no
    damage to the text; DRY sampling also stopped the copies but garbled
    2–5 replies in 8, so it is not used. The assistant's own chats are
    unchanged: they keep the seed and their reasoning, and so does the
    persona's crisis judge, whose verdict should not vary. mecha persona show now reports how many of a persona's replies over the last week
    repeated an earlier one in the same chat, read from the chats themselves.

  • The knowledge-graph page names the embedder mecha-graph actually uses:
    harrier-oss-v1-0.6b on a llama-server at :8081, launched by
    scripts/llama/mecha-embed-server — not ollama with nomic-embed-text,
    which mecha-graph dropped in 0.1.1. The page says plainly that the
    repository has no installer that sets the server up from nothing.

  • Voice expressiveness settings the speech model ignored are no longer
    sent as if they worked.
    The live model, Chatterbox Turbo, drops
    exaggeration and cfg_weight, so the worker's 0.8 / 0.3 and the mood
    nudge changed nothing. The speech server now lists the controls its model
    honours and refuses one it would ignore, and the worker sends only those.
    CHATTERBOX_MODEL=original loads the slower model that does honour them.

  • A persona's earlier chats no longer vanish after a restart. An unlock
    lives in mecha serve's memory, so a restart ended it while the page still
    showed the persona, and its earlier chats came back as an empty list. The
    page now notices the lapsed unlock and locks, says when the list could not
    be read, and shows that it is loading.

  • messages = false is an answer now. Switching messages off left
    mecha setup listing it as outstanding, with a failing exit, every time
    it ran, because the setting it is stored in could not tell "off" from
    "never asked". mecha setup and mecha features now show it declined,
    with mecha features enable messages as the way back, like every other
    feature. It is still off until you switch it on.

  • The persona file editor works on a phone. Tapping a field no longer
    zooms the page and leaves it zoomed: every editable field is at least 16px
    on a touch screen, the size below which iOS Safari zooms (text mode too).
    The Save bar is solid instead of letting the text scroll visibly under it;
    the highlight on the field being edited is centred; text boxes refit on
    rotation and after Discard and no longer jump the page while measuring; and
    sections take less width on a narrow screen. The Settings form shares the
    same styles and gets the same fixes.

  • A persona draws itself from whatever it writes about itself. Follow-ups
    to #444: a display name with punctuation ("Mara O'Brien") no longer eats
    the first word of what the persona is doing; an extras entry that opens
    with the persona is taken as the persona and cast from its own words,
    where it used to be refused or drawn as a stranger; an extra that names the
    persona in passing is refused before drawing, saying how to fix it; self
    beside the character's name drops only the duplicate it made; and the
    library is read once for the self-cast and the guard instead of once each.

  • A command that ends non-zero no longer leaves a model hold behind.
    mecha eval with a failed case, mecha batch with a failed item, and a
    refused mecha run exited without removing their file in
    ~/.mecha/holds/. A dead process's hold never blocked a model switch, so
    the files only piled up. Every such exit now releases the hold first.

  • A chat no longer resends a refused call for minutes. If a tool
    refuses the same call the same way, turn after turn, the run now stops
    after seven tries. You get an answer saying what could not be done, instead
    of up to forty identical attempts. A call you or a policy turned down never
    counts toward the seven. One persona chat did this with a
    picture, twice, and held the GPU while another chat was drawing. Persona
    chats also get the notes the assistant already had: after three identical
    results the model is told that nothing is being learned and to try another
    way, which is what rescued the assistant's two such runs, and after six to
    say what is blocking it instead.
    [agent] loop_guard = false switches the stop off.

  • A name not in the image library no longer blocks a picture. When
    the assistant names someone in a picture who isn't a library character,
    they are drawn from the description it gave, as an extra, and the result
    says so. A character waiting for approval is still refused, and persona
    chats are unchanged.

  • A locked page no longer says how much it is hiding. The personas grid
    drew a hidden · N tile and the image library a "N locked entries hidden"
    line, which told whoever held the phone there was something to find. Both
    are gone, and so is the hidden_locked count in /api/personas and
    /api/library behind them: a locked page now reads exactly like one with
    nothing locked, as a locked entry's own URL already answered 404 like a
    missing one. The persona list no longer names a locked character that a
    visible persona uses as its portrait either (character is null in
    /api/personas until unlocked, a problem line naming it is left out of the
    list and of a save's answer, and an entry that will not load counts as
    locked); the link itself is kept.

  • Unlocking on the new-persona form now offers locked characters as
    portraits.
    The form read its character list once, when it opened, so
    the lock button refreshed the persona grid and left the portrait list as
    it was; it now re-reads the list on every lock change, and a relock drops
    a locked portrait the form had already chosen.

  • The document cache is private all the way down. ~/.mecha/documents/
    and every directory under it are now created owner-only (0700), and every
    file in it 0600. Before, only the per-file entry was, so the cache root and each entry's ocr/
    folder were left at the umask default, and another local user could list
    which PDFs had been read, by hash. An existing cache is tightened on its
    next write. mecha document prune now fails on a cache it cannot read,
    instead of reporting "removed 0" (#410).

  • Image edits that move someone or change a pose no longer come back
    unchanged.
    The cause was the prompt, not chance: the edit model returns
    the same picture when the prompt describes the whole scene or asks to keep
    the picture unchanged, and the tool's own wording asked for both. On the
    same 12 seeds, a caption stood someone up 0 times, "Have Maya stand up"
    alone 8 times, and the same after naming what to keep ("Keep the style,
    the lake and the blanket unchanged.") 12 times. The tool now asks for that
    last form. As a
    safety net, it also compares each edit's layout with the picture it edited.
    When they match, the result says so and tells the model to retry once with
    an instruction, or to redraw from the library when the picture came from
    it. A second match in a row says stop and tell you.

  • A run can no longer mark a rule down by rejecting its own draft. An
    edited or rejected draft counted as your verdict on the drafting, in the
    appraisal and so in rule tenure and replay priority, whoever made the edit
    or the reject. Now it counts only when it is stamped as yours, as a
    release already did. A stamped act that is not yours counts as neither,
    and acts from before the stamps existed keep their sign.

  • The appraisals' hit rate counts only predictions that could miss. A
    chat answer or a run that staged nothing leaves the owner no draft, task or
    workflow to act on, so no_act is the only act that can be observed there
    and predicting it is a hit by construction. sessions appraise read those
    as "hit rate 100%" over four such scores; it now names them as forced and
    prints no rate until a prediction risks a miss. Scoring, and the surprises
    replay priority reads, are unchanged.

  • The appraiser is not asked to predict an act where none can happen.
    When a run's output offers no draft, task or workflow, and the run never
    touched a task, mecha distill leaves the expected act out of the
    appraisal's question and drops one the reply carries anyway. The row
    records that the harness withheld it, and sessions appraise counts
    such rows as "not asked".

  • A voice call whose browser never connects ends after 90 seconds, not
    at the fifteen-minute idle timeout. Until now it held the speech models
    for the quarter hour, and for a call into an incognito chat it kept the
    voice worker's log silence on for every other call in that time. Restart
    the voice worker to apply it.

  • A model switch waits for a reply in flight instead of failing. The
    router refuses an explicit load with model limit reached, try again later while the loaded model is answering a request. mecha model use,
    and the web chip that runs it, now retries every second until the
    request ends, within --wait-secs. Before, the switch failed at once and
    loaded the old model back. The first live switch from the chip hit this.