Fixed The browser download shows its progress
Playwright's installer now runs on your terminal with its own progress, and a failed download names the installer's exit code.
devnotes
Release by release, newest first. The full history lives on GitHub.
Playwright's installer now runs on your terminal with its own progress, and a failed download names the installer's exit code.
A host name the resolver cannot encode is refused as unresolvable instead of crashing the browser's proxy.
The launch check reads the browser's command line, so the plugin is documented for those two, and a platform with no readable process list says so in doctor.
The browser plugin, off by default, gives the web researcher and the search verifier a sandboxed headless Chromium that runs a page's scripts and returns its text in the same shape the plain web fetch does.
Every request a page makes passes through a checking proxy that applies the web fetch's public-address rule, the proxy is proven at every launch, and no cookies, profile or storage carry between calls.
The doctor command gains rows for the browser's package, binary, launch and sandbox, each with the hint that fixes it.
The phone's permission prompt marks a tool as untrusted from its own declaration, so a plugin tool that pulls in web content is labelled like the built-in web tools.
The record left on disk stays out of the model's view until the model resumes it, so a bare hello no longer inherits the last session's task.
Each entry says its runtime, where its weights sit and its window as the planner prices it, a file not yet set up is set up after one question, and what cannot launch says why.
A reserve now sits beside the compute margin, so a dense model no longer dies at its trained window, and a launch that would leave layers on the CPU says so on its line.
A model whose attention alternates full and sliding layers is priced per layer kind, so one the full-attention figure used to refuse is now offered.
An install of the pinned-experts engine beside a model's shards is sensed, fingerprinted and launched through the same keyed, loopback, verified-stop path as the other runtimes, with its config copied through an allowlist.
A llama.cpp launch is priced from the file's dense weights, projector and attention cache, with a mixture-of-experts model's experts held in RAM when the GPU cannot, so a large model no longer comes up at a tiny window.
One sentence names what is short and the remedy, and a swap plans against the memory it will have so the serving model keeps serving when it is refused.
The smallest window that holds the system prompt and tool schemas is computed, and a server that serves less is refused before the first turn.
Subagents read the root's window at every spawn, so after a model switch the next delegation sees the new window, and a child that cannot fit is not run.
localharness start with no config finds the models on the machine and sets them all up on one Enter, or offers a verified download when there are none.
The cache type, multi-token-prediction drafting and vLLM's reasoning and tool parsers are derived from the model at launch, and the launch line names what was derived.
No temperature is sent unless you set one, so the model's own default is no longer overwritten on every request.
localharness model --autostart writes one pinned systemd user unit, and --script prints the exact launch as a shell script with keys shown as placeholders.
A backslash then Enter breaks the line on every terminal, and Shift+Enter does too on a terminal set up to send it.
terminal.keys picks the chord for each from a short list, refuses two you set that collide, and is read from the machine config only.
A llama.cpp or vLLM model is now a named preset that init writes from what is on the box and /model switches.
It reads the served, trained and fitted windows, sizes the context itself when it launches llama.cpp, and says when they disagree.
/effort off, low, high or max bounds how much a model may reason per request, on every surface.
A dropped connection or a restarting server is one bounded wait and an identical re-send, never a failed turn, and no tool call runs twice.
A sleeping phone thread now wakes at its last answered request, so a turn that ended blank stops making every next reply blank.
The banner, --version and update had been stuck on an older release, so update kept offering one already installed; a test now holds every version string to one.
The Discord environment variables and the web config section are no longer read, as earlier releases announced.
List, add, edit, test and remove MCP servers for the session's agent without leaving the terminal, with connections refused in an untrusted workspace.
Trust snapshots now hash environment and header values, not just their names, so a changed secret re-prompts at the next start.
The task evidence line is no longer appended to the reply; it stays on the event bus and in the agent packet.
The question is one sentence and comes after the harness's first commit in a project, not when the workspace opens.
A once-per-project question asks whether localharness is named as a co-author on commits it helps make — a hand-run commit is never touched, and no answer means no trailer.
A picture can be attached from the terminal, Zed, the phone or Discord, and rides in the user turn beside the text.
Each image is counted by the model's own resize rule, downscaled or refused when too large, and named when compaction leaves it out — never dropped silently.
With a new task tool the model keeps the objective, decisions, artifacts, checks and stop boundary, citing the human turns behind them, and ordinary questions get no record.
Files a record references are re-read before every request, so their current text survives compaction, edits and restarts.
A delegation carries a structured brief and a runtime-observed status, and a record retires only once every delegation is integrated and every check passed or waived.
Nudges carry their origin, so a human correction stays human content and compaction keeps the lineage.
Requirements bind to actual tool receipts and artifact revisions, so failed, missing or stale evidence cannot mark a task complete.
The agent can hold a few earlier tool results for its next step, and the packed request restores them or says the step must be narrowed.
An event-bus package that was declared but never imported is gone, and a test fails if a declared dependency ever goes unused again.
Packages the code uses but received only through other dependencies are now declared in their own right.
After a while with no phone attached, no turn running and nothing waiting, the mobile session writes its conversation beside its session log and shuts itself down, and your next message wakes it with the conversation continued. Opening the app alone does not wake it. The wait is yours to set with --sleep-after.
Ctrl-C or a service stop puts a live session to sleep the same way, so a restart continues the conversation. The + button, or deleting the sleeping chat from the drawer, discards it.
Everything the session held goes with it — the model client, the memory store, the embedding model and the consolidation timer — so an unused server holds little more than the phone's token.
A permission mode looser than your configured one is not restored from it, lines typed ahead are never in it, and a conversation wakes only in the folder it slept in.
The handler the REPL installs for a running turn used to leave the default one behind, so the next Ctrl-C ended the process instead of stopping it gracefully.
After a new chat, the phone's taps went to the previous chat's REPL, which also kept that chat's loop and memory model alive for the life of the process.
The command is localharness mobile, the plugin is mobile and so is the install extra; the old web names still work with a warning until a later release removes them.
The dreaming pass could hold every CPU core for hours while nothing was happening. It now runs within a time budget, on a few threads, one window at a time, and your next message still cancels it at once.
Where requests go and which keys they carry come from your machine's config only, a project's own files can only make things stricter, and a cached embedding model loads from a checked folder with no network call.
localharness plugins enable asks the plugin's questions and checks the result, and /plugins enable in a running terminal session does the same and restarts it with the conversation kept.
The config folder, your keys, the phone token, grants and every session log are created readable by you alone, and an older folder is tightened at the next start.
Each of image, mobile, memory, dispatch and autoresearch has its own page in the docs, with a doctor check and a trust-project flag for a start that skips the trust question.
Core now holds the loop, the tools, the config and the permissions, while image, mobile, memory, dispatch and autoresearch ship as plugins you switch on or off behind one additive plugin API.
One memory plugin fills a section of every turn's prompt, and with memory off that section stays empty and no memory tool is registered.
Discord now runs as the dispatch plugin with its own settings in the config file, and the old environment variables still fill an unset setting, with a warning, until a later release removes them.
The autoresearch plugin now mounts the autoresearch, experiment and propose commands, and a command whose plugin is off exits with a hint naming the command that turns it on.
A project's own config can no longer switch the capability floor off; only the global config can, and start warns when a project tries.
A test now reads the docs and the code and fails when they disagree.
Search ranking, idle replay and duplicate detection now all judge similarity with a local embedding model instead of rule-based gates, tag graphs and keyword heuristics.
Idle consolidation replays the session's own history to rank memories and group related ones, and each new memory starts with the track record of whoever wrote it.
With archival enabled, memories that score below the store's own usefulness line are archived and can be brought back exactly with the memory restore command.
In auto mode a call on the blacklist is queued for a human while the turn carries on, and you answer later with /pending, /approve and /deny, ctrl+y and ctrl+n, or Discord reactions.
A summary is written back into the session history, so later requests stop re-summarizing, and a context-window overflow from the server is recognized and retried against the window it named.
Evicted tool results now say which tool and path they replaced, an unknown tool name suggests the nearest match, and hard refusals state that nobody can approve them.
The first time a workspace is opened you are asked once whether you trust it, and after that everything runs except a named blacklist of risky calls.
A workspace with earlier LocalHarness sessions behind it is recognized and trusted with a one-line notice instead of a dialog.
The separate offer to create a project workspace folder is gone, and answering yes to the trust question now records trust and creates the folder together.
Writes to system locations such as /etc, /usr and the Windows system folders now ask every time, while temporary directories are exempt.
You can now switch to unattended with /mode in the terminal, with mode in Discord, or from the Zed picker, where before it was config-only.
The ask-and-remember behavior is unchanged but you now choose it in config or with /mode, and an older config naming auto now simply loads as auto.
A single deterministic check, subagents included, asks you when a call crosses your project boundary or looks destructive and stays quiet otherwise.
Your always and never answers are stored per workspace in your home folder, and a grants file inside a project is never read, so a cloned repo cannot approve itself.
You can switch between guarded, trusted and read-only per session from the terminal or Discord, while unattended stays config-only.
The new acp command runs an Agent Client Protocol server so replies stream into Zed, edits land in its review pane, and permission prompts use its own dialog.
The bot posts the question and you answer with a reaction for allow once, always in this workspace, or no.
The shipped deny list only caught the world-writable chmod form at the start of a command, so forms like find with exec or a command after && slipped through.
The row now shows the current phase such as thinking, writing or tool call with a live token tally, elapsed time, and a red silent marker when no output has arrived for a while.
A generation that locks into repeating itself is aborted as it happens, retried with a repetition penalty, and ends the turn with an explanation if it happens again.
The maximum turn duration now defaults to no limit, so slow hardware is no longer cut off mid-task, and you can still set a number to pin one.
A subagent given write also gets edit, edit returns a diff of its change, and write over an existing file reports how many lines changed.
When your config sets no maximum, the request leaves the limit out entirely and the model generates until it is done, bounded only by your context window.
The cap computed from your window size in the previous release is deleted, and a number you write in config is still honored exactly.
A config written by an older init keeps its pinned default cap until you delete that line or set it to null.
With no cap in the request, a truncated reply is reported as a full context window and points you to compaction rather than offering to raise a cap.
When your project has no workspace folder, start offers to make one, and a declined offer is remembered for that directory.
A new start option and terminal setting let you watch the model's reasoning as it streams.
The README now documents what is supported on Linux and on Windows.
A reply that comes back empty no longer ends the turn as if the task had finished.
The bash_exec tool now has the coreutils it needs on Windows when the harness is started from PowerShell, and a command that could not run is reported as a tool failure.
The startup summary no longer deletes its own warnings, and an agent name containing brackets no longer breaks the agent picker.
A .localharness folder in your project now carries its own config, agents, memory and state layered over your global setup, with the workspace value winning on conflicts.
You are asked before configuration that reaches in from outside your project is applied.
A recall scope setting chooses workspace or global memory, and /memory promote moves a single memory across that line on purpose.
Init --workspace scaffolds the project folder, doctor reports the layering, and config show prints the effective merged config.
In a workspace session the file tools are confined to the project root by default, and config errors now name the file that set the bad key.
Deny patterns written in an overrides file and in org-level config now reach enforcement instead of only being stored.
Doctor now uses the same token counter as the running session and reports the mode it actually resolved, so a drifted provider setting shows up as a note instead of a phantom failure.
When a stale model name made the tokenizer check fail, dependent checks are now skipped and labelled instead of producing a second failure.
The warning now says how far off the estimate can be depending on content type, including that it can be badly wrong on Chinese, Japanese and Korean text.
The status line no longer under-reports speed when the server sends several tokens per streamed chunk.
If a model's tokens-per-chunk ratio has never been measured, the live rate is left blank rather than guessed, and the learned ratio is saved so later sessions start accurate.
Recording a new speed no longer wipes other information stored on the same model entry.
It upgrades an installed copy to the latest release using whichever installer set it up, with a check-only option and a refusal on source checkouts.
start accepts a model flag that is never saved to config, and a list-models flag shows what is being served without starting a session.
model --download fetches a repository, and a file option pulls just one file such as a single quantization.
For a managed llama.cpp server, doctor flags a Vulkan-linked binary on an AMD GPU and names the rebuild flags to use.
When the configured model name is stale and the server hosts exactly one model, start switches to it and prints a line saying so instead of failing.
Reading a binary file now returns a short error, and the compaction threshold setting is now actually honored.
The context window setting now means the full served window, and the harness reserves room for the reply in one place.
The gentler full compaction now triggers before the last-resort mechanical cut at every window size.
The number of tokens a request may generate is now capped so prompt plus output always fits the window.
Usage is now measured against the usable budget after the reply reserve, so compaction triggers marginally earlier.
Servers with very small windows now start and run, and only windows too small to hold any reply are refused.
A second emergency cut within one turn now logs an escalated message saying what to change.
Tokenizer requests now name the session's model, so servers hosting several models accept them.
An endpoint that answers with an error is now reported as rejecting the request, with the server's own message, instead of as unreachable.
Both spellings of the reasoning field are handled, so reasoning models show correct decode speed and their reasoning text reaches the message.
Events and history now carry the full output with honest truncation flags, though the model always saw the full result.
Restored content stays pinned for the rest of the turn, so a read, evict and re-read cycle no longer traps the turn.
The pre-filled name is replaced as soon as you type, paste or backspace, so the next command is no longer garbled.
The speed ledger now ignores timing windows too short to be trustworthy on vLLM.
Both now resolve the same effective budget, name any per-model pin, and match it to the right model's window.
Trace packs no longer emit empty tool messages, and a dead endpoint now gets one probe cycle instead of repeating it.
A model_context_overrides setting gives a model its own token budget, honored at startup and when swapping models with /model.
The docs now cover tested DGX Spark setups, with measured numbers labelled as measured and unmeasured depths stated plainly.
The error now says which model's window it is rejecting.
It no longer writes overrides silently and stays honest when the write fails.
An untouched default context budget now auto-fits to the served window with a printed note, while explicitly configured values still abort honestly.
When a server never shows a native tool call, the client makes one more request with the XML syntax taught to see which mode works.
With an endpoint flag, init picks the model when exactly one is served and lists the served ids when it cannot choose.
validate and components now tell you to run init when the config is missing, as doctor does.
Budget and stuck-recovery summaries stay within the current turn.
The input-box hint disappears after the first submit, and managed LM Studio liveness is checked at the endpoint.
The mcp dependency is pinned below its next major release, which had broken start with a raw traceback.
Verified tokens per second is saved for each provider and model and shown in /model and the input-box status line.
The terminal prints a line showing how much of the window was used before and after history is summarized.
Exhausted parse retries now fail the turn, and malformed or dropped tool calls become parse failures instead of crashes or fake answers.
Stop now re-checks after a forced kill and refuses to report a stop it cannot confirm.
The /model picker no longer clobbers typed text, and a stale Ctrl+C can no longer exit the session.
The terminal and Discord channels show when a reply looked like a tool call but nothing parsed, with the retry count and the runtime flag to check.
DeepSeek's native tool-call formats are now recognized and named as a failure, though converting them remains the serving runtime's job.
An inconclusive capability probe is now retried instead of downgrading the whole session.
The slot advisory now compares the per-request window against your configured budget instead of just counting slots.
A provider_type that disagrees with the running server now recovers with a logged warning instead of failing.
The harness can start, stop and swap the model server itself for vLLM, llama.cpp, Ollama and LM Studio.
/model can stop the GPU incumbent and launch a peer on another framework, then swap back, restoring the old server on failure.
Ollama and LM Studio now count using the model's own vocabulary and template in-process, and vLLM and llama.cpp count the whole rendered request.
The README lists honest per-runtime status, and new pages walk through real configs for llama.cpp, Ollama and LM Studio.
A crash where budget code fed message fragments to the exact counter is fixed, and Ollama or LM Studio activation failures no longer orphan the daemon.
It no longer answers that the model "list" is unknown.
/model can now switch between models served on different endpoints or frameworks, using peers configured under extra_endpoints.
The picker groups models by endpoint and framework, and unreachable peers are noted instead of causing an error.
It is auto-detected, counts tokens exactly, discovers its served window, and has completed a live agentic tool-call round trip.
A configured context larger than the endpoint serves now fails loudly instead of being silently truncated.
The context budget is clamped below the served window, and unsupported-parameter errors in native mode retry correctly.
Stopping a managed Docker server now waits until the old container name is actually free, so the relaunch after a swap no longer fails with a name-already-in-use error.
The managed server is given more time to finish in-flight connections before it is forced to stop, and it reports an explicit error if the name never frees.
The server stop now runs off the main event loop, so the session keeps responding while the old server drains.
The new bench pack command turns a bench results folder into a manifest and a file of graded trajectories, one record per run labeled pass or fail.
Only completed scenario results are packed, and live session files are skipped because they contain real user activity.
If any home path, key or secret pattern appears in the packed content, the build fails before anything is written.
Each pack manifest stamps the harness version and source tree so packs can be regenerated for each release.
Typing a bare /model now opens the menu with the first model highlighted, so you scroll or filter and press Enter once to switch.
The model menu and listing show each registry model's quantization and its measured tokens per second on your hardware.
The picker now offers only live and registry models, while Hugging Face cache repos stay in the printed listing.
The server.local_models setting names local checkpoints with their own extra arguments, and picking one in the /model menu restarts the managed server with it.
The input box status row now shows the model name and elapsed time while a swap loads, and clears it on success or failure.
In Docker mode the checkpoint folder is mounted read-only and served under the registry name, so the picker name is the model id.
A crashed Docker startup left a defunct process that made the readiness check wait for its full timeout, and it now fails fast and shows the end of the server log.
Typing /model followed by a space opens a completion menu of the models your server actually serves.
The list of models is loaded in the background at startup and refreshed on every /model run, and the menu never fetches from the server itself.
If the server is unreachable or returns bad data, no menu appears and typing a model name or number works as before.
The picker works in both the persistent input box and the classic prompt, and it filters without regard to case while completing with the exact id.
When the model echoed back the confirmation instruction on a turn with no tool calls, that meta line could be shown as the whole answer, and it is now recognized and discarded.
Echoed confirmation exchanges are removed from conversation history the same way bare confirmations already were.
The nudge messages now ask for only the single word CONFIRMED so the wording stops inviting an echo.
Typing a slash opens a scrollable menu of all slash commands with descriptions above the input line, with arrow keys, Enter or Tab to accept, Escape to dismiss and typing to filter.
The bare /memory overview now shows buckets, child tags with counts and the most recent memories as a tree.
The /memory show command draws a memory's supersede chain with ancestors above, the current memory highlighted and descendants below.
The banner and the version flag now read the version from the source code, so editable installs no longer show a stale version.
The new /memory command lets you browse the agent's memory store by tag hierarchy, starting from an overview of buckets, child tags and recent memories.
The /memory show command displays a memory's value, tags, confidence, source, supersede chain and whether it is eligible to be injected into prompts.
The /memory forget command previews first and retires the memory only after you confirm, keeping it auditable in history rather than deleting it.
The /memory search command runs the deterministic search path and shows ids so you can follow up with show or forget.
The command makes no model calls and is safe to run mid-session against a live store.
A small chapter is no longer folded into a much larger one when the two share too few child tags, and both chapters stay independent with the refusal logged.
A newly mined fact that conflicts with an older one on the same subject and differs in a config value now supersedes it, with the chain preserved.
Turns where nothing was injected now record a zero row so per-turn coverage accounting stays complete.
A turn whose model output was only the confirmation word could be given a previous turn's reply as its answer, and it now gets one re-prompt and otherwise an honest message that no answer was produced.
The classification call no longer times out while waiting behind a running stream, and a message queued during classification is upgraded to a live nudge when the verdict arrives.
Leaving the REPL just after an answer now lets turn finalization complete within a short grace period instead of cancelling it.
Evidence now accrues only on real growth, so candidates seen in a single sitting age out unless their topic genuinely recurs.
Concrete example tickers in researcher role prompts were replaced with placeholders because small models repeated them in real answers.
The memory shelf injected each turn is now logged as a co-firing event, marked as injection so it stays distinct from model-initiated retrieval.
A kill-switch setting turns ambient trace recording off, and a weight setting discounts injection traces when discovery scores co-firing.
Subagent results now begin with an explicit run-complete header, and a child final that only announces further work is labeled as no result.
The web researcher now leads with an ANSWER line, or an ANSWER NOT FOUND line that explains why.
The baton gate gains a max_nudges setting that defaults to the previous behavior.
A small time-budgeted slice of consolidation work now runs after each final answer, tagging untagged memories, naming discovery candidates and running promotion and prune checks.
Memories saved with remember are now classified into a bucket and child tag when written, and a classification failure never blocks the save.
Writes now keep the first bucket and refuse a different one, and the micro-pass repairs older rows that ended up with two buckets.
A first successful use of a tool is now checked against the durable store, so the same fact is no longer recorded again and again.
Final sentences such as "I will search for" or "Please wait a moment" are now recognized as announcements instead of answers, at both the orchestrator and the web researcher.
The doctor command now reads the server's slot count and, when there are several, prints the single-slot remedy along with the per-slot context math.
The reference architecture docs now carry the same parallel-slot note on every llama-server launch line.
Every message you submit in the input box now leaves a permanent line in the scrollback, marked when it was queued or sent as a nudge.
The spinner now shows as a status row above the input box instead of inside its border, and the row disappears when the agent is idle.
The dreaming status for background memory consolidation now appears in the same status row.
Tool names with colons or dots, such as MCP and plugin tools, are now recognized when the model replies in XML fallback format.
Bench now clamps its context ceiling to the window in your config instead of the scenario's larger assumed window, so overflow no longer reaches the server.
Scenarios that set the tool-call limit to zero no longer discard a correct answer as over budget, and a refused call gets an explanation instead.
Memory tools are no longer registered when a scenario's allowed tools list is empty.
When the emergency context floor shrinks an oversized prompt, it now publishes a compaction event instead of cutting silently.
A YAML file in the agents folder now overlays the built-in explore, web-researcher and search-verifier configs, and bad values fail with a clear error.
When a reply ends by announcing its next step instead of doing it, the agent is pushed back once to do the work or give the final answer; it can be turned off in config.
The web-researcher can make more tool calls and run longer, because many research assignments were hitting the old ceiling.
The terminal input box now stays live while the agent works, and it can be disabled with a setting to restore the old between-turns prompt.
Messages typed during a turn are routed either into the running turn as a nudge or into a queue that plays back afterwards, and a leading exclamation mark forces a nudge.
The tool counter and thinking indicator draw inside the box frame, which fixes a screen freeze when Ctrl+C landed mid-burst.
Tool names are sanitized so llama.cpp no longer rejects the whole request and pushes every MCP or plugin tool onto the XML fallback.
Bash discovery now skips the WSL launcher, searches git-bash locations, honors an environment override and decodes wide-character output.
LocalHarness can now be installed with pip, uv tool install or uvx, so the CLI works from any directory instead of only inside a repo checkout.
A GitHub Actions workflow builds, smoke-tests and publishes the package whenever a GitHub Release is created.
Source distributions now ship only the source and docs metadata instead of the whole repo.
In XML fallback mode the model is now always told how to call tools, so servers whose chat template drops tool schemas no longer leave it unaware its tools exist.
Tool results are replayed as user turns so template-less servers no longer reject the conversation after the first tool call.
The CLI survives consoles that are not UTF encoded, bash_exec launches git-bash from paths with spaces, and file tools and bash agree on where the temp folder is.
The reachability probe now races address families, so doctor and bench agree on whether a local server is up.
When the first matrix entry does not match your active backend, bench now uses your config file, and it stages its fixtures automatically.
Commands previously ran under the platform sh, so bash-only syntax such as brace expansion silently misbehaved.
Results now say whether a file was created, overwritten or left unchanged, and an identical rewrite tells the model not to repeat it.
The repeat window is cleared once a recovery warning fires, so a model that complies is no longer re-warned on stale counts.
The warning is now a durable message in history instead of vanishing from context on the next step.
When a turn is stopped as stuck, the agent now gets one tool-less wrap-up of what is done and what remains.
During long multi-stage tasks, the model's short stage statements now appear as dim lines opening each chunk of tool activity.
When a reply hits the output limit mid-tool-call, the call is suppressed and the model is told to write in smaller pieces.
Background memory consolidation now defers while a turn is in flight and measures idleness from the end of the turn.
The system prompt now states the launch directory, so new files land in the project instead of the home folder.
The tag-discovery embedder no longer reloads on every idle pass or prints loader output over the input box.
A quick connection probe runs before the inference queue, and waits behind a busy server are logged and bounded by a new configurable limit.
Each agent tool completion now prints a line saying whether the sub-agent completed or failed, regardless of how the model narrates it.
Patterns ending in a bare double star now return files, and the tool description explains tilde expansion and where relative patterns start.
Turning off the schema writer setting now stops both the writer and the staleness recheck.
Healing a chapter no longer takes over another chapter's identity, and the recheck now rotates across all chapters instead of starving.
The create command now errors when an agent already exists, and a force flag opts into replacement.
An invalid generated config now triggers one regeneration with the error fed back, then a truthful abort, instead of a raw validation error after you approve.
A newly created agent now appears in the agents list and the delegation tool without a restart.
Your follow-up is now added to the description so the correction reaches the generator instead of being discarded.
Phrases like never mind or forget it now cancel the wizard, and the quit command cancels the wizard before it exits the session.
The CLI gains a version flag, and the model command now warns when your default model is not among those being served or downloaded.
A startup failure now tears everything down in order and exits with an error instead of hanging, and an unreachable model is reported with its real cause.
A failed switch restores the previous model and says so, and the context window is re-read from the server for each switch.
The config-dir flag now applies to the overlay, kill-file, audit log and history, so separate instances no longer share state.
Pressing Ctrl+C during generation now cancels only the turn, and a second press while cancelling exits.
A user correction now only disputes a related fact and is quarantined otherwise, and unknown slash commands are rejected immediately.
The first start after an upgrade now folds new default deny patterns into your config additively, with a backup, and a config migrate command with a dry-run option does the same on demand.
Consolidation progress now goes to a log file while the terminal shows a quiet dreaming status that never draws over the input box.
XML tool-call mode and several background call sites now stream, so timeouts and cancels no longer leave the server generating for no one.
Grep now skips hidden, vendor and binary files, stops at a file and time budget, and returns partial results with a note instead of hanging.
Setting an agent axis now validates against the agent model and writes to the user overlay instead of always failing.
The new grouping mechanism is included but disabled by default after it failed its regression gate on the first live proof.
Destructive docker, systemctl, kill, shutdown and reboot commands are now denied by default, and existing installs must re-run init or edit their deny patterns to pick this up.
The shipped sudo pattern required a literal colon and never fired on a real command in any release.
Setting a workspace root confines write and edit targets and the bash working directory inside it, and it is off by default.
Doctor no longer builds a doubled path and no longer passes the model check on an HTTP error.
The novelty fold threshold default is raised so near-duplicate facts still merge but distinct facts are safer from erroneous merges.
Facts that cluster around one topic are now written up as a chapter — and the chapter survives its own growth. When new facts join, the grown cluster supersedes its old chapter instead of minting a parallel copy, and a chapter can never be absorbed into a cluster built from its own members. Topics only relate on two independent signals — embedding similarity plus a shared salient token, never similarity alone. One caveat carried from the changelog: the eval's passing verdict holds under its standard grounding rule and flips under a stricter one — disclosed as such, not hidden.
Transcript records that a mining pass read but did not use are no longer lost — they queue in a residue ledger, and later idle passes re-mine them under a bounded attempt cap, so nothing loops forever. Every pass now reports its own coverage: what it saw, what it cited, what it queued, rescued, or retired.
Extraction could mint near-duplicates of a fact it already held. A novelty gate now checks every candidate against the existing record — only genuinely new information earns a new entry; everything else folds into the fact it repeats. The gate is deliberately conservative, so distinct facts never merge.
Only user-authored evidence can advance a fact's confidence. The model restating its own earlier claim no longer counts — an agent cannot talk itself into certainty. Limit, stated in the changelog: a numeric claim grounded in a tool result and one the model merely asserted still earn equal trust today; a source-reliability gate is planned.
Two correction bugs closed: correcting a fact now retires the stale value even when the corrected value was already on file, and the supersede directive is recognized wherever it appears in the extractor's output, not only in the one spot the parser used to look.
The terminal now renders each tool call as a compact one-line summary with its markup escaped — bracketed text inside a call no longer corrupts the line it prints on.
Three test-suite holes shared one disease: point the live benchmark at a misconfigured server and it could still come up green — every run erroring, nothing measured. A success check that matched on empty text is now rejected when scenarios load; the budget-cap test demands the capped behavior itself — one action taken, the follow-up absent — instead of accepting any failure as proof; and the endpoint health check and the tests it guards now resolve the same pinned model and server from one place, refusing loudly to run unpinned. Verified against a live endpoint: green only when correctly pinned, loud on everything else.
Alongside the existing capture floor — a tool error that later resolved, a stuck loop that recovered — every tool outcome is now scored against that tool's own track record, computed inside the database with no model call and no token cost. A normally-reliable tool erroring is a surprise, and becomes a memory; a tool failing the way it always fails stops being news — the junk the old floor had no way to suppress. A tool with too little history to predict from is scored as a cold start rather than guessed at, and the capture floor still covers it from the first turn.
When you correct the agent — "no", "I meant…", "actually…" — the harness now records it. A direct correction supersedes the most recent fact it was likely about, with the original text preserved behind a dispute marker, never erased; anything less clear-cut is filed as its own quarantined fact in your own words. Everything is reversible through fact history, and repeating a correction confirms the existing record instead of duplicating it. The trigger is a plain word list, not a model — a correction that uses none of the words is missed, and a false trigger costs one stored record.
Every new write in this release lands below the injected memory's visibility line: stored and searchable, but kept out of the prompt — so it cannot change what the agent does — until an idle consolidation pass confirms it. Corrections and disputed facts are held back further, for a deeper reconciliation pass. A single config lever reverts the whole live path to the old capture floor while the scorer keeps logging — a kill switch committed in advance, not improvised after. The injected block still does not steer the agent's first move; this release is capture, and says so.
The gate comparison ran offline: one real session trace, replayed through the old gate and the new one, measured against the full set of surprising failures rather than a hand-labeled proxy. The new gate captured every one; the old floor missed a few. The junk-write comparison depends on how strictly junk is graded — under the strictest grading it inverts — so both gradings ship in the repo's report tooling rather than as one headline number. The trace carried no expected failures and no recovered stalls, so those paths are proven by unit tests, not a live occurrence — disclosed, not declared won.
Every run of the harness is now a session with its own record. When one ends, the harness distills a one-line, payload-first summary of what actually happened — the error you resolved, the stuck loop it recovered from — and files it to the agent's memory; a sitting with nothing of substance writes nothing rather than padding with filler. A fresh session then answers "what did we do last time?" straight from its injected memory block, without a tool call. Summaries written when context is compacted persist the same way, so what got compacted away isn't lost to the next sitting.
The injected memory now carries a Recent Session History block — each past sitting on its own line, tagged with a relative day and clock time, newest first, capped to a short window; older sittings stay in the store and remain searchable. When a sitting has no error-lesson to lead with, its summary leads instead with a trimmed slice of what you asked — so a pure conversation is no longer invisible to memory. Rendering reads the session records directly and stays byte-stable within a day; the whole path runs without a model call.
While the model is generating, the terminal shows an animated "thinking…" spinner that clears the instant real output arrives — a tool-call line, the answer panel, or the next prompt. It replaces the occasional static "Working…" line, so a long generation no longer looks like the box has hung.
The root agent is now created and selected as "orchestrator" rather than "default", matching the architecture's own vocabulary. Existing installs migrate on first start and keep every memory — the agent file and the whole memory store are adopted under the new name, one-time and crash-safe. If you already run your own agent named orchestrator, the migration refuses rather than merge or overwrite anything, the root keeps its old name, and a console note explains how to resolve. The old name still redirects to it, and orchestrator is now reserved for the root.
The act-guard — the nudge that turns a stated intent to go look something up into an actual tool call — used to ask the model to restate its final answer when no tools were needed, which could surface a narrated duplicate of the reply you had already been given. It now requests a marker the harness swallows, and the original reply is delivered unchanged. This retires a leak that had been live since an earlier release.
Agents now write, rank, consolidate, and retrieve long-term memory on their own — no memory prompt-engineering. There are two write paths: a deliberate save, and an automatic gate that captures lessons from the harness's own prediction-error signals — a tool call that failed then later succeeded, a stuck loop that recovered — at no extra model cost. Nothing is ever overwritten: a conflicting fact supersedes the old one, which stays retrievable on request, and every fact carries provenance back to the episode it came from.
Which facts earn prompt space is decided by activation scoring — used-often plus used-recently — computed inside the database at query time, so ranking costs nothing. When you go idle, a background "sleep" pass promotes lessons seen across more than one episode, decays unused facts out of the visible index without deleting them from the store, and trims a soft cap by demotion rather than silent deletion. Your next message cancels an in-flight pass at once.
The in-prompt memory is an index — fact names with one-line, payload-first descriptions — not the full bodies, which are pulled on demand. Reads and retrieval no longer perturb its bytes; they accumulate in a staging ledger instead of reordering anything. The bytes move only at genuine writes, consolidation folds, and day boundaries, keeping the inference server's prefix cache intact between those points — stability that is load-bearing on a long prompt, not cosmetic.
An over-window document read now persists its gist-and-schema tree, so a later search routes through that structure — the gists steer the search, the leaf records anchor the answer. The number-provenance net from the over-window work extends here too: a figure promoted into a gist that traces back to no source leaf is flagged, never silently kept.
A promoted lesson's payload now survives every render layer — the line budget for the index no longer truncates the discriminating detail out of a lesson before it reaches the prompt.
Two shell-holding specialist roles left the default roster after a live quality pass — one hung on an undeclared dependency on its first run, the other worked but had no business holding a shell by default. Both remain as documented opt-in examples. What ships now is exactly the set whose fences the security model can vouch for. (Released ahead of the in-progress memory milestone, which keeps the number below.)
Hyphenated terms, tickers, and slashes used to leak into the search syntax and error out. Query text is now quoted term-by-term, so punctuation is content, never an operator.
A question the model could answer without tools sometimes ended on a self-referential note instead of the answer. The loop now tells the model only its last reply is shown, and unchanged answers are confirmed with a sentinel the summary resolves back to the real text.
Overlapping local runs used to stack prefills toward one shared GPU — the freeze-the-box failure mode. Inference toward a local endpoint is now serialized by default, in-process and across processes. Decode is engine-serialized anyway, so serial costs roughly nothing in wall-clock.
Fetches stream to a hard body cap instead of buffering unbounded responses — one pathological URL can no longer eat the box. When the cap engages it is surfaced in the retained page, never silent.
Over-window chunks got bigger, to where recall peaks before lost-in-the-middle sets in: better recall and fewer leaves to reduce, at neutral wall-clock. A recall-and-cost win, not a speedup — scope stated honestly.
When a document bigger than the context window is combined in stages, every figure in the final answer is checked back against the verbatim section notes. Anything untraceable is surfaced as a warning — never silently rewritten.
The threat model now lives in SECURITY.md: trust boundaries, the structural injection defense, and — plainly — what is not built yet.
A cruncher subagent splits oversize documents structure-aware and reads every section — nothing truncated. Content handles move results between agents without re-inlining the bytes.
Untrusted-ingested web or tool content can never co-reside with host-mutating tools in the same agent — defense-in-depth above model refusal.
The test suite runs without a configured home directory — a clean checkout is green from the first command.
The start command drops you straight into the default agent; the subagent picker moved behind a flag.
Web search ships as a core dependency — no extra install to give an agent the web.
Agent responses render as Markdown instead of raw text.
The context counter handles literal special-token text instead of failing the turn.