Skip to content

CLIO Coder 0.8.0

Choose a tag to compare

@iowarp-clio-coder-release iowarp-clio-coder-release released this 13 Nov 00:06

0.8.0 is the stable release of 0.8.0-rc.1, with the same product code; the notes below are the 0.8.0 notes.

CLIO Coder 0.8.0 is for people who run a coding agent beside other people, other agents and other tools, and for anyone who automates one: researchers on shared login nodes, teams in one repository, and scripts that drive headless run. Shared folders, the sandbox, headless run, setup and installs behave more strictly and more predictably. A per-project store keeps results outside the working tree, reports are reviewed before they leave the machine, and long sessions, large repositories and streamed answers stay fast. Several exit codes, defaults and permissions change, so read the Upgrade notes first.

Highlights

  • Share a folder safely. A second clio-coder in a folder another terminal is using opens its own session with its own panes (#420). Session state is owner-only, and project settings can only tighten safety.
  • A sandbox that hides more. Contained commands cannot read other agents' logins, shell histories, browser profiles, cloud and editor token files, Kerberos caches, the kernel keyring, CLIO Coder's config directory or the desktop app's launch token. A project's secret files stay hidden in every checkout and worktree layout.
  • A required sandbox that stays required. Under safety.sandbox: required, git push, gh, ssh and other outward commands leave the sandbox only as one literal command with short-listed options. Checks that run what workers wrote run in the sandbox too.
  • Headless run built for automation. Every --json stream ends with one run_end frame, exit codes say what the host decided, cost caps trip on routes that report no usage, and model traffic follows HTTPS_PROXY.
  • A per-project store. store keeps results and datasets outside the working tree, shared with workers and linked worktrees, with a record of where each file came from and whether it has changed.
  • Reports you review first, and no call-home. /report and clio-coder report show the masked draft before anything is sent. A diagnostic share is encrypted for the maintainers, uploaded as a secret gist in your own GitHub account, and deleted by forget or after 180 days.
  • Setup and installs that work the first time. Setup asks what you have and tests the route before saving it. A lab can publish one setup file for clio-coder configure --import, a new guide covers HPC login nodes, installer, npm, pnpm and Bun installs share one lifecycle, and Windows gets a native launcher.
  • Delegated harnesses follow your project. Claude Code, OpenCode, Codex and Pi runs get the project's compiled rules, and work in another repository follows that repository's rules.
  • A fullscreen terminal you can copy from. A mouse selection pastes what was written, wrapped paragraphs, code and CJK text included, without the gutter or glyphs (#453). Selection works over search and overlays, the wheel follows its speed, and a ↓ latest marker says when newer output waits below.
  • Faster where it shows. The first frame draws before earlier runs are recovered, a streamed code block redraws only its open line, long sessions stop re-hashing the whole conversation, and parallel workers reuse the first worker's prompt cache.

Upgrade notes

Headless run and automation

  • Every full clio-coder run --json stream ends with exactly one run_end frame carrying exitCode, outcome, outcomeDetail, error and the safety summary, also after --timeout or a signal. Read the result from run_end. The model's last turn_end or agent_end no longer settles it, because the host can fail a run after the model finished (a denied call that changed nothing, an undelivered worker).
  • New run exit codes. run --agent verifier exits 1 when the verdict is fail and lists the checks under Failed checks:; the --json result frame gains verdict and failedChecks. A turn that closes with an empty message after narrating beside a tool call exits 1 with the narration on stderr; 0.7.0 printed the narration as the answer and exited 0. A closed stdout reader (run ... | head -1) exits 141, and any other stdout error, such as a full device, exits 1 with one line after the run and session settle. run --model with a pattern that matches no model exits 2 instead of 1. run --agent exits 129, 130 or 143 on SIGHUP, SIGINT or SIGTERM after writing its result.
  • Three cases that exited 1 now exit 0. A run in a workspace with no declared or derivable checks no longer fails because its verify call found nothing to run; the observed: line and the JSON observed field say no checks are declared, and a named check that resolves to nothing is still an error. A shell command that wrote a file counts as a write, so a run whose allowed shell write landed is not failed as a no-op because a later command was refused. A run started with --turn-mode answer or --turn-mode proposal exits 0 when a tool call was blocked along the way and names the blocked calls on stderr and in the JSON result; without a turn mode, or with change, a run whose requested command was refused still fails.
  • run --agent accepts --timeout. On expiry the worker is aborted, the run is recorded as canceled and run exits 124. 0.7.0 refused the combination as a usage error.
  • run with no saved chat route uses the one usable route for that run, says so on stderr (a notice frame under --json) and saves nothing. The route can be a saved target that holds its key, a stored login or an API key in the environment. With several usable routes it exits 2 and names each as --target <id>. A route whose runtime has no default model needs --model; without it run exits 2 and names the flag. Copilot sign-in and saved Copilot targets, loopback servers, targets defined in project settings and the target reserved for memory (context.memory.target) are never used this way; when the memory target is the only saved target, run says so.
  • run --agent <id> --json writes an admission_refused frame (agentId, message, exitCode) when dispatch admission refuses the agent, and a headless run whose only usable target is reserved for memory exits 2 at that refusal.
  • Headless run prints one observed: line on stderr after the answer (tool calls, refusals, writes, standing checks) when the run called a tool; --json-events terminal carries it as turn_end.observed. Stdout and exit codes are unchanged.
  • Piping a task to bare clio-coder (echo task | clio-coder) exits 2 and points at clio-coder run "<task>" instead of discarding the task and exiting 0. An empty stdin or /dev/null keeps the normal launch.
  • clio-coder with a piped stdout (clio-coder | tee log) boots non-interactively instead of drawing the TUI into the pipe. CLIO_CODER_INTERACTIVE=1 still forces the TUI.
  • A dispatched edit worker whose write and execute calls were all refused by policy and that changed nothing fails with worker_no_work instead of exiting 0. A review pass from a reviewer that made no successful tool call, or that claims checks it never ran, needs an operator decision instead of closing the loop.
  • Under a cost cap (run --max-cost-usd or safety.limits.sessionCostUsd), a call on a priced route whose server reports no token usage is charged an estimate from its request size, with one notice, so the cap trips on such routes. A call that failed before the provider streamed anything (connection refused, DNS failure, proxy refusal) is not charged. In text mode the notice is repeated once in the exit summary on stderr.
  • Running workers are stopped once session spend reaches safety.limits.sessionCostUsd (default $5) in every mode, not only under run --max-cost-usd. Sessions that used to overrun the ceiling quietly will see workers stopped. Workers on free, zero-rate or unpriced routes, delegated runs and runs already waiting on their merge card keep running.

Safety, sandbox and permissions

  • Under safety.sandbox: required an outward command (git push, gh, ssh, rsync, sbatch and the other CLIs CLIO Coder names) leaves the sandbox only when the whole line is one literal command whose options are on that CLI's short list and name no file, directory, program or config. The call's working directory is judged like git -C. Any other form, such as gh pr create --body "$(cat <<EOF ...)", a pipe, a redirect, an environment prefix or a wrapper, runs inside the sandbox like any other command, so a push or gh call written that way fails there. Write a pull request or issue body to a file and pass --body-file. The line also stays inside when a file it would send is a masked secret, when the repository's hooks or executable git config changed during the session, when a push would go to a local repository, for every scp, and for npm publish or pnpm publish without --ignore-scripts. The safety model lists every condition.
  • At yolo the destructive-command floor reads any line holding a command substitution ($(...) or backticks) as raw text and blocks it when that text names a destructive command, even inside a quoted message, a here-document, a comment or a command meant for a remote host. Pass such text through a file instead. After a cd to anything but a literal path, a relative delete of ., .., * or a system directory name (bin, lib, var, home) is blocked.
  • Trusted project settings may only tighten safety.sandbox, safety.sandboxNetwork, safety.snapshots and fleet.permissions.mode, and can no longer set integrations.runtimePlugins or trustProjectImports. A team that committed safety.sandbox: off must move it to user settings. A runtime plugin must be a bare npm package name or a path under the config runtimes/ directory; relative paths such as ./x.js are refused.
  • A project may also only tighten safety.limits.*, fleet.limits.toolCallsPerRun and fleet.limits.internalRunTimeoutMs, and may only switch the review watchdog on or make it more frequent; a looser project value is ignored with a warning.
  • A target that project settings point at a non-loopback URL is never sent your stored or environment provider keys, on turns, side calls, target probes or System One engines; the run fails naming why, and only --api-key applies to it. A project target on a loopback URL gets them only when its runtime needs no credential, such as Ollama. Define a credentialed endpoint in user settings.
  • A turn uses only the key CLIO Coder resolved for its target. A target naming auth.apiKeyRef reads from the environment only auth.apiKeyEnvVar or its runtime's own variable (such as GOOGLE_API_KEY), not another name for the same provider (such as GEMINI_API_KEY).
  • Session transcripts, spilled tool output and runs.json are owner-only (0700 directories, 0600 files), and boot applies those modes to CLIO Coder's existing state subdirectories. A group-shared home loses that access on upgrade; share a session with clio-coder telemetry share instead. doctor warns when the state or data root is open to other users, and doctor --fix tightens a root it can prove is CLIO Coder's.
  • Extension commands run inside the main session's OS sandbox when admission contains them, as bash does. An extension command that wrote outside the workspace at default is blocked with bash's write hint; it can retry with unsandboxed: true, which raises the reviewed sandbox-escape ask.
  • Contained commands get their own persistent cache under CLIO Coder's cache directory (sandbox-cache) instead of writing ~/.cache or ~/.npm: XDG_CACHE_HOME, npm_config_cache, PIP_CACHE_DIR, UV_CACHE_DIR and PLAYWRIGHT_BROWSERS_PATH point there, so the first contained install is cold. A tool that hard-codes ~/.cache and ignores XDG_CACHE_HOME fails on write; the hint names the variable to set.
  • On a client with no fleet.nodes configured, or when placement puts the worker on this host, a worker under safety.sandbox: auto that the orchestrator expects to be sandboxed refuses to run instead of running commands unsandboxed. A timed-out bubblewrap probe is retried first.
  • Slurm, PBS, LSF and Flux client commands (squeue, sbatch and the rest) run outside the shell sandbox behind the same approval as ssh: an ask at default, the judge at yolo. A script that calls sbatch itself stays contained and fails there, and so does a workspace script named like one of these commands (./sbatch, bin/ssh). /loop --command and job poll commands get the environment bash gets (credentials scrubbed, safety.sandboxPassEnv honored) instead of an internal allowlist.
  • Typed tools refuse the same home credential files the shell sandbox masks (gh, hub and cargo credentials, ~/.password-store, keyrings) and every /proc/*/environ.
  • Approving project hooks also pins the repository scripts they name, so a project whose hooks run repository scripts asks for approval once more after the upgrade, and again whenever one of those scripts changes.
  • A task merge into a checkout with overlapping uncommitted work is refused even when merge.autoStash is set, instead of reporting merged and leaving that work conflicted.
  • Arena contenders get an allowlisted environment: the base variables, safety.sandboxPassEnv and their own target's credentials. Other targets' keys, other secret-shaped variables, HERDR_*, SSH_AUTH_SOCK and display variables do not reach them, so a check that reads another variable needs it in safety.sandboxPassEnv.
  • Fleet loop checks, gates and gate baselines, research objectives and gates, and clio-coder verifiers dry-run run in the main-session sandbox that host verification's checks use, because they run what workers wrote. A check that writes outside the workspace, the scratch roots and the package caches, or reads a masked secret, fails there. safety.sandbox: off runs them bare, as does auto on a host with no sandbox backend; required without one refuses them.

Removed and renamed

  • clio-coder gui --token and #token= launch links are removed: a private server prints a #ticket= link with a single-use launch ticket. A browser signed in under 0.7.0 deletes its stored launch token without using it and shows the reconnect prompt; clio-coder gui opens a fresh link. A desktop app background service installed by 0.7.0 needs no manual step: clio-coder upgrade, or else the first clio-coder gui of this version, replaces its stored launch token and restarts it.
  • Slash names renamed or retired in 0.8.0 answer like any unknown command: /health and /systemone (now /usage health); /skills, /prompts, /agents and /interop (now /library skills|prompts|agents|interop); /workspace (now /extensions) and /workspace off (now /extensions leave); /library reload and /extensions reload (now /reload library|extensions); /branch (now /fork [name]); /peer (now /panes peer [--cwd] <agent> [brief]); /share (now /fleet share [run-id], also for ACP clients). Four names became keys: /interrupt is Alt+S (Send now), /editor is Alt+G, /background is Ctrl+G then d, and /notifications is Ctrl+G then x (dismiss the oldest notice); typing one of these four names says which key replaced it and clears the composer. /resources, /plugins, /output and /share export|import are no longer recognized, and /eggs and /archive still work but are hidden from / and /help. The upgrade notice lists the moves once.
  • Retired spellings: /doctor deep is a usage error (use /doctor --deep), and /delegate is /run: /run <recipe> <task> runs a CLIO Coder recipe and /run <agent-id> <task> (or acp:<id>) delegates to an external ACP agent. /loop list and /loop cancel <id> are accepted for one more release; use /loop and /loop stop <id> --now.
  • /settings accepts only a settings area as its second word; anything else is a usage error. A fleet.permissions.escalation.timeoutMs above 2147483647 (Node's timer maximum) is clamped to that maximum, and one below 1 to 1.
  • /settings lists the settings people change. About 40 tuning rows (keybindings, memory and working-set tuning, route cooldown, model favorites, safety judge rules and others) left the menu; Advanced gains "Edit settings file" and "Check setup", and every key still works in settings.yaml.
  • New slash aliases: /clear (/new), /exit (/quit), /init (/context init), /login (/settings connections), /cost and /status (/usage), and /undo (/rewind).
  • List overlays share one set of action letters, and an old letter does nothing: x removes, cancels, declines or supersedes the selected row in Tasks, the steering queue, Memory, Fleet Runs, Decisions, the Library and Interop, asking once first; r refreshes the Library and R restarts all extensions; o orders /tree; m steers a fleet run and Enter opens its detail; s switches Interop scope; Tab opens a Library review's paths.

Setup, homes and installs

  • An older CLIO Coder no longer restamps a home a newer one last used: the terminal asks before continuing (default no), run and ACP exit 2 unless CLIO_CODER_ALLOW_OLDER=1 is set (run --agent goes on without restamping), and doctor names both versions and the clio-coder binaries on PATH. A home last used by 0.5.x gets its pending migrations at boot, a home that ran migrations under 0.5.5 or earlier is not mistaken for a newer one, and settings provisioned before the first launch (dotfiles, images, CI) are left as written.
  • A first launch on a home the installer scaffolded opens setup instead of saving the first route it detects, and a model server found on a local port is used only after you say yes. On Linux the question names the listener's owner and defaults to no when another user owns it.
  • A new home no longer downloads terminal panes on its first launch: CLIO Coder says once that they are not installed, and clio-coder panes install adds them. A home that already has panes still updates them when the pinned version moves.
  • Setup sends the model one short test request before it saves a route and saves only after the model answers or you choose Save anyway; --no-verify skips it and configure --id ... --verify opts in. Adding a connection in /settings, the desktop app's guided setup and the configure settings menu send the same test.
  • A target that names its key variable (auth.apiKeyEnvVar) uses that variable before the key auth login stored for its runtime, so two targets on one runtime no longer both send the stored key. When the variable is unset the stored key is used, and auth status and doctor say so. Targets with auth.apiKeyRef, targets that name no variable, and OAuth targets resolve as before; an OAuth target ignores auth.apiKeyEnvVar and keeps using its login.
  • HTTPS_PROXY, HTTP_PROXY and their lowercase forms apply to model requests, discovery probes, OAuth refreshes and web fetches, and doctor shows the proxy in effect. localhost, 127.0.0.1 and [::1] always go direct. A model server on a LAN address (LiteLLM, Ollama, llama.cpp) that went direct in 0.7.0 now goes through the proxy, with its credentials, unless NO_PROXY names its host or covers its IP address. NO_PROXY matches exact names, domain suffixes (example.com, .example.com and *.example.com all cover api.example.com), an optional :port, and, for IP addresses only, CIDR ranges (10.0.0.0/8, fd00::/8) and IPv4 wildcards (192.168.*); NO_PROXY=* turns the proxy off. A connection error on a proxied request names the proxy.
  • install.sh and install.ps1 refuse a Node download when nodejs.org serves no SHASUMS256.txt.asc, when the file holds no valid signature, or when a key outside the Node release keyring signed it. A mirror without a signature, an unreachable keyring or a gpg that cannot read the keyring still warns and installs on the checksum; CLIO_CODER_REQUIRE_SIGNATURE=0 accepts and =1 requires a verified signature.
  • install.sh, install.ps1 and clio-coder upgrade resolve the release channel outside the current directory, so a repository's .npmrc does not pick the version, and a channel that resolves below the installed version is refused. clio-coder upgrade --channel latest still leaves a pre-release for the stable release, and a direct installer run does so with --leave-prerelease (-LeavePrerelease in PowerShell).
  • clio-coder uninstall and reset keep and name a root they cannot prove is CLIO Coder's own (for example CLIO_CODER_CONFIG_DIR=~/.config), and refuse CLIO_CODER_HOME set to the home directory. A data or cache directory under CLIO_CODER_HOME that holds files CLIO Coder did not create is kept and named, and the command exits 1; one an earlier version created is removed.
  • On Windows the installer writes a native clio-coder.exe launcher instead of clio-coder.cmd. Installing over an earlier version replaces the .cmd with a short stub that points at the exe.
  • Outside a Git repository only the current directory's CLIO-CODER.md loads; parent handbooks are no longer inherited.

Other behavior changes

  • A provider's stated retry wait (Retry-After) is honored even with chat.retry.maxRetries: 0. Waits grow with each attempt, a retry chain ends after 30 stated waits, and plain-text headless run prints a stderr line when a retry waits 5 s or more.
  • An HTTP 200 answer that is not an event stream (a captive portal, a JSON error, a server that ignores stream: true) fails the turn with its status, content type and the start of its body, instead of ending as an empty reply.
  • On hosted routes (cloud and subscription), a call that never produces its first token is aborted after chat.retry.streamStallMs (180 s) instead of chat.retry.firstTokenStallMs (600 s), which now applies to local and self-hosted endpoints.
  • The default compaction token ceiling (context.compaction.maxTokens) rises from 200,000 to 400,000 tokens and is the working budget on every route, so a model with a larger window works further into it before compacting. Set a lower ceiling to limit input cost.
  • Workers can use up to fleet.limits.toolCallsPerRun tool calls unless their recipe sets a lower maximum, instead of stopping at the recipe's estimate. The defaults rise to 300 tool calls and 45 minutes per run, the coder estimate to 150 and the tester estimate to 100.
  • A memory lesson backed only by a quote from a repository file or by a command that cannot fail (echo, ls, true) waits for the operator instead of becoming durable, so expect more pending lessons in clio-coder memory list.
  • Telemetry prunes itself once a day under the default retention (90 days or 1 GiB). Each sweep spends at most 2 s removing files and never delays startup, so a large home can take several days to come under the limit; clio-coder telemetry prune --apply prunes at once.
  • Enter in the model picker and /model <name> apply the model to this session at once; press s on a picker row to save it for the project or globally.
  • A second clio-coder started in a folder whose pane host another open terminal still shows says so and gets its own pane host, up to four per folder. Past that it runs in its terminal without panes, with its own session. Separate git worktrees keep their own pane hosts.
  • CLIO Coder's answer voice changed. A finished fix opens with the plain news, a reply names whether a claim was measured, inferred or untested when that matters, and filler and exclamation marks are gone. Headless runs and yolo sessions open the final reply with where the task stands against the request (done, partly done or not done).

Project store

The store guide covers the tool, the CLI and choosing a backend.

  • A new store capability, reached through the gateway, keeps a project's results and datasets outside the working tree, shared by the main session, its workers and the project's linked worktrees. A tag is a named container (classed input, output, cache or archive) and a blob is a named file in it; refs take the form <tag>:<blob>, such as results:summary.parquet.
  • Eight ops: tags, create, list, stat, get, put, note and remove. put copies a workspace file into a tag and records where it came from, including the producing run_script run, and every blob keeps a write-once history. stat reports drift (none, changed, missing or unrecorded), and get returns the path of a read-only copy to pass to data, read, run_script or an MCP tool.
  • Reads run without an ask. create, put and note are judged as writes at their real target, and remove or a put that replaces a blob asks and names the blob and its size. Workers read the store and write only into tags a dispatch grants them (tags); a grant to a worker on an SSH fleet node is refused at admission.
  • run_script takes a store blob as a declared input, as <tag>:<blob> or the path store get returned, reads it in place and names it in the used record of a later put.
  • clio-coder store reaches the store from a shell: tags, ls, stat, history, verify, put, get, rm, rm-tag, adopt (move the store of a checkout that moved) and where. put creates a missing tag as an input tag. rm and rm-tag without --yes print what they would delete and exit 0, and a missing tag exits non-zero.
  • The store lives under the data directory at store/projects/<key>/tags/, with owner-only files. clio-coder reset --data, reset --all and uninstall without --keep-data remove it with the data root, and nothing can recover it afterwards.
  • An opt-in clio-core backend is experimental in 0.8.0. clio-coder store backend clio-core selects it only when every probe passes (it needs a clio-core build at commit 6c54cdbf or later), a selected clio-core that cannot attach fails the call and never falls back to local, and store backend local switches back. Switching never moves data.
  • The built-in coder, researcher and scout workers use store and data without extra setup, and the per-turn hint names the project's tags when the store holds any. The science-data pack 0.2.1 starts from the store and requires CLIO Coder 0.8.0.

Reports and sharing

  • /report [bug|feature|question] [summary] and clio-coder report [bug|feature|question] draft a report for CLIO Coder's maintainers; --last or --session <id> adds what CLIO Coder observed in a session. The troubleshooting guide documents every step and flag.
  • You see the draft exactly as it will be posted, with local paths, outside URLs, user, host, project, branch, remote and target names, e-mail and IP addresses and secrets masked. Nothing is sent without your send key in the TUI (s, never Enter) or your answer or --yes in a shell. The review refuses a draft that still holds this machine's names, paths or hidden characters, and --yes does not override it. Outside a terminal without --yes, or for a refused draft, report sends nothing and exits 2.
  • Sending posts a public issue (bug, feature) or discussion (question) on iowarp/clio-coder through your signed-in gh, else a prefilled browser form, else a file with the link to paste it into. It first searches GitHub for the same problem and asks before adding to a match or filing a regression; under --yes, --on-duplicate decides and the default stops with exit 3. report status, send <id> and forget <id> manage drafts and sent reports, and report security points to a private security advisory.
  • A diagnostic bundle is opt-in (--bundle mechanics --consent debug|dataset): the session's telemetry under the report profile and, with --transcript [N], its last turns, scrubbed. Every byte is checked for this machine's identifiers, and a hit refuses the bundle with exit 1. Without --share it stays on this machine.
  • No call-home: sharing is explicit, one item at a time, and only from your own shell. report ... --share and clio-coder telemetry share ... --send --consent debug|dataset preview what goes, encrypt it so that only the maintainers' key opens it (X25519, HKDF-SHA256, AES-256-GCM) and upload it as a secret gist in your own GitHub account through gh. report forget <id> and telemetry share forget <shareId> delete the gist, and the next report or telemetry share run deletes a share once it is 180 days old. Nothing runs at startup.
  • An agent never sends or shares. The agent's report capability only saves a scrubbed draft for your review, workers do not get it, and --share, --send and a clio-coder report run from a session's bash send nothing, even at yolo. Over ACP and in the desktop app a report is sent only by a second command, /report send <id>, with the text that client was last shown, and a bundle is attached only after the client grants a permission request.
  • After one of its own failures CLIO Coder may suggest /report, at most once a session and once a week; report.offers: off turns that off. The send step can opt into a once-a-day check for a maintainer's reply (--reply-check), which never runs in CI or with CLIO_CODER_UPDATE_CHECK=0 or NO_UPDATE_NOTIFIER set. When an upgrade fixes an issue you reported, CLIO Coder says so once and thanks you.

Terminal and commands

The commands guide lists every command and key.

  • In fullscreen a mouse selection copies what was written, not the screen: a wrapped paragraph or list item comes out as one line, a wrapped code line as its source line, and the turn glyph, the gutter, the prompt bar and the code indent stay out. Tables copy as drawn without the gutter, and a tab copies as three spaces (#453). Wrapped Chinese, Japanese and Korean text copies back as written, with no space added at a wrap and none lost between Korean words.
  • You can select and copy while transcript search is focused or an overlay is open, including the transcript beside an overlay, and click the search box's buttons. Choices in an overlay still move only on keys. Pointer movement and window focus never act as keys, so a nudge between two Ctrl+C presses does not cancel the exit.
  • The fullscreen wheel follows its speed: one row for a single notch, up to six for a fast spin, five times that with Alt (a local macOS terminal, which accelerates the wheel itself, moves one row per report). While the transcript is scrolled up, a ↓ latest marker on its last row says newer output exists, and a click returns to the live edge. A resize keeps a scrolled-up reader in place and drops a selection whose text re-wrapped.
  • Copies in quick succession show one flash, and over SSH a copy says Sent to terminal clipboard (OSC 52). Search matches use the theme's colors. Inside Herdr and other terminal multiplexers, fullscreen tracks the mouse only while a button is held. A clean exit in regular mode clears the input box, its rails and the footer before the exit summary.
  • The command palette lists everyday commands first, led by the ones you use most, and finds a command by alias, verb, letters in order or purpose. Enter runs the highlighted command when you typed its name or the start of it and it works without arguments; after a bare / or a looser match, Enter completes the row like Tab and waits. A command typed in full runs on the first Enter. A mistyped command names the closest one, runs nothing and keeps your draft, and a mistyped flag answers with one usage line.
  • /run <id> also starts a configured external (ACP) agent. A fleet agent of the same name wins, acp:<id> forces the external one, and flags an external agent cannot take (--model, --target, --worktree and the like) are refused in one error.
  • /settings has seven areas named for what they hold (Models, Chat and display, Workers, Context and memory, Safety and limits, Workspace, Advanced). Old area names still open them, typing always filters and * pins a row. /config opens Settings on Connections in place, also during a turn, and a Connect by URL row there runs the Quick Connect steps of clio-coder configure inside the session.
  • /usage gains a Health tab, Alt+U opens a one-page dashboard, /help opens with a "Start here" task list, and the model picker shows each row's prompt-cache switch cost.
  • Ctrl+C backs out one layer in every overlay, like Esc, and list overlays share the same keys for filter, select, detail, back and paging. The Ctrl+G action menu lists only actions that work in the current layout. /panes shows as unavailable without a pane host, and music leaves the palette and menus while it is off.
  • /reload prompts (and bare /reload) re-reads prompt fragments, agent recipes, the project handbook and project rules in a running session, says which fragments changed, and rebuilds the clio_docs index. The safety rule pack still needs a restart.
  • /restart first checks that the build on disk can start and refuses, keeping the session, when it cannot. /restart <text> hands the text to the restarted session as its first turn. A running session warns once when the build it started from is replaced on disk and keeps a "build replaced · /restart" line in the footer.
  • A running CLIO Coder names its build in its process title (clio-coder 0.8.0-dev@67b3247). --session-file <path> keeps a live record of the session, rewritten at every turn boundary and on every move into or out of a wait, and replaced by the exit record when the session ends.
  • Attended sessions ask the model for a one-line reason before a call that will park for approval. When a project's agents or playbooks replace yours, the session says which once at startup and points to clio-coder doctor.
  • An old-school arcade cabinet is hiding in the composer; it only wakes up for the right two words.

Setup, sign-in and providers

  • First-run setup asks what you have (a key, a subscription or a model server), names the provider from a pasted key and picks the recommended model. Anything CLIO Coder already found is offered first, and a model is set up before the folder question. When a model server refuses without a key, setup offers to store one and rechecks the same address.
  • A lab or site can publish one setup file. clio-coder configure --import <path-or-https-url> shows where prompts will go, asks once and connects (without a terminal it prints the changes and asks for --yes); first-run setup offers the same as "A setup file from my lab or team". The file may name only targets, the variable or sign-in profile each reads its key from, and the chat and fleet routes; a literal key or any other setting is refused.
  • Sign-in from configure and auth login opens your browser on a desktop and goes straight to the device or copy-code flow over SSH or without a display; auth login --method browser|device overrides the choice. Choosing "Later" or a failed sign-in ends setup with nothing saved and names clio-coder auth login <id>.
  • clio-coder auth login never echoes an API key: a terminal gets a masked field, the key can be piped on stdin (printf %s "$KEY" | clio-coder auth login openai), and --api-key warns that it exposes the key in shell history and the process list.
  • A missing key, an unreachable model server or a missing model reads as one sentence that names the fix, the same in doctor, run, the TUI banner, a failed prompt and the desktop app.
  • Setup and the /model picker do not offer embedding or rerank models as chat models; naming one explicitly still selects it. Setup never offers a probed model id that holds control or format characters, and reads at most 1 MiB of a probe's answer.
  • A session that starts with the project's configuration trusted lists what each connection the project defines still needs: the missing key or sign-in with its command, or, for a connection at an address the project chose, that CLIO Coder sends it none of your keys until you define it in user settings with its own key variable (auth.apiKeyEnvVar).
  • Setting up in the terminal with a key from an environment variable offers to store a copy for the desktop app, which cannot see your shell's environment; only connections that name that variable use the copy, and only while it is unset.
  • auth logout lists a target's stored key under the target id and removes exactly the credential you pick; the runtime's own key is accepted as runtime:<id>. Removing a target drops only the credential that only it used, and the removal line says which were kept.
  • The anthropic and anthropic-max runtimes continue Anthropic message threads on api.anthropic.com, so a follow-up request sends only the new messages; a target with its own URL keeps sending full requests. After about 270 s without a reply, the next request starts a new thread.
  • GitHub Copilot routes compact against the prompt budget Copilot enforces for the model (200K tokens for Claude models and 100K for Claude Haiku 5.5 on the default tier), and a Copilot context-limit refusal is treated as an overflow, so a long session compacts and retries. A copilot-sdk target can opt into the long-context tier with contextTier: long_context. An autonomy or posture change keeps the cached prefix instead of restarting the SDK session, and cache-write tokens are counted once.
  • Cost: a target priced with only input and output bills cached prompt tokens at its input price instead of $0. An OpenRouter model missing from the catalog stops at the session cost ceiling. Side calls (a side question, a handoff round) and compaction summaries are checked against the ceiling on every route, priced or not.
  • The OpenRouter probe checks the API key, so an expired key shows as refused. An OAuth refresh that fails on a network error says so and retries on the next call instead of asking for a new login.
  • Prompt prefixes cache across sessions and across workers of one recipe: per-session facts moved into the session's first message, and a worker's tool list no longer varies with its task. The attended prompt is about 6.5 KB shorter, and an experimental prompts.profile: v2 setting (restart to apply) uses a leaner main prompt, about 24 KB attended against 33 KB; v1 stays the default.

Sessions, loops and yolo

  • A second clio-coder in a folder gets its own session and pane host instead of joining the first one's pane (#420). The desktop app opening a session another CLIO Coder still has open leaves it open, and ending or deleting a session takes the same lock as resume; ACP session/delete reports session_open for a session in use. Two read-only runs in one checkout no longer fail with checkout_writer_lease_held (#420).
  • A state-file lock held from another pid namespace on the same host (Apptainer --pid or --containall) is judged by that namespace's own pid and the boot id, so a host session and a container session respect each other's settings, credential and admission locks. On kernels without NSpid (before 4.1) it waits out a 30 s backstop instead. Both sides need this version.
  • /loop --until-stopped, the job tool's until_stopped and the chat.loopsUntilStopped setting run a loop until you stop it, with no run count, deadline or continuation cap. It backs off instead of pausing on repeated outages, and past three continuations each further one waits 1, 5, then 15 minutes. The cost ceiling and the loop guard still apply (#450).
  • A command job can wait on several conditions at once: give it also with an argv and until per further condition. CLIO Coder checks every condition on each poll and matches only when all hold, /loop status lists every condition, and a deadline wake names the ones still pending.
  • A follow-up turn already running, or one queued after the loop's condition matched, is not killed or dropped by the loop's --for deadline. A loop that uses up its runs before its --until condition matches says so, and a waiting loop that reaches its deadline first wakes the main turn once to report or continue (#450).
  • At yolo, a turn the loop guard stopped (the hard tool-call ceiling or an identical-call loop) continues as a counted continuation and ends after three. A scheduled job turn it stopped reports failed, not cancelled, and does not count toward the job's pause; ACP clients get max_turn_requests. Pressing Esc before the hard stop leaves the turn stopped.
  • Contained yolo runs dispatch plans (several tasks, compete, council, a Scout or Documenter pipeline, remote placement) with yolo authority instead of refusing them as needing you. Workers keep default's permits, ask routes and sandbox, and the main session keeps its sandbox, snapshots and safety judge.
  • Yolo's floor refuses deleting your home directory spelled ~yourname, and judges a delete or shred after a literal cd from that directory. A scheduled job command is judged as the uncontained call it is.

Security and sandbox

The Upgrade notes cover the changes that can break a workflow. The safety model is the full reference.

  • What every sandbox hides. Other agents' logins (Claude Code, Codex, Gemini, Copilot), tool token stores and shell histories; browser profiles (Firefox, including its snap and flatpak copies, Chrome, Chromium, Brave and Edge), VS Code's global storage and cloud, registry and agent token files; the token and key files of local Jupyter, IPython, ipyparallel and code-server services (a kernel started inside the sandbox still runs); and your Kerberos ticket caches in the shared temp directories and the one KRB5CCNAME names. Under bubblewrap the seccomp filter refuses the kernel keyring calls. Typed tools refuse the same paths.
  • CLIO Coder's own files. Every sandbox hides CLIO Coder's config directory behind one mount and binds back only what a contained command reads (skills, plugins, extensions, agents, playbooks, prompts, and settings.yaml unless a target declares auth.headers), so a credential store rewritten during an OAuth refresh stays hidden. Every sandbox also hides the desktop app's launch token directory (<state>/gui) and the pane-host sockets (<state>/mux/run, <cache>/run). Typed reads refuse those paths, settings.yaml while a target declares auth.headers, and mcp.yaml while it gives a server an env map; clio-coder mcp list never prints env values.
  • Project secret files. A worker's secret scan covers the checkout its task worktree was cut from and every worktree linked to it, in any repository layout, and task worktrees under .clio-coder/worktrees are scanned as roots of their own. A cached scan is renewed after any write, edit, bash or run_script call and reused only while every secret it found, and each directory above it, is still where the scan saw it. Host verification, its base replay and extension runtime sandboxes apply the same masks. On Linux the masks hold through every other mount of the same filesystem (such as WSL2's /mnt/wslg/distro), and contained commands are refused when the mount table cannot be read.
  • Environment. Contained commands do not inherit JWT-valued variables (such as SLURM_JWT), *_HEADERS variables, URLs that carry a token as the username, BW_SESSION, webhook variables or any variable whose value looks like a credential. run_script refuses a declared BASH_ENV, CDPATH, CLIO_CODER_INTERACTIVE or autonomy key. Every subprocess CLIO Coder starts (run_script, verify, hooks, MCP servers) carries the session's autonomy ceiling and contained-yolo pin, which a caller can tighten but not lift.
  • Outward commands under required. Beyond the upgrade note: the CLI must not be planted on the PATH bash runs with or in a writable tree, the host must not be this machine, and options are spelled in full or as a cluster of listed flags (git push -uf, rsync -av). Outward curl does not follow redirects, git with GIT_CONFIG_SYSTEM= or a -c core.sshCommand=-style override stays inside, and npm publish or pnpm publish leaves only when the package directory holds no masked secret and its secret scan was not capped. A command that reaches an outward CLI through a project file (a PATH= assignment, LD_PRELOAD, NODE_OPTIONS, GIT_SSH_COMMAND, PYTHONPATH and similar, a sourced file, an alias, a function or hash, and npx, pnpx or bunx) stays inside, and scheduled command jobs, which always run outside the sandbox, are refused. unsandboxed: true stays for a command the sandbox broke and runs only when the operator names or approves it.
  • Sockets. safety.sandboxUnixSockets: owned masks only your own Unix sockets inside a bubblewrap sandbox and leaves system daemons' sockets reachable; block stays the default. Under owned, the sockets of root-equivalent daemons (Docker, Podman, containerd, CRI-O, k3s, BuildKit, LXD, libvirt and Incus) stay masked in the worker sandbox.
  • Approval cards. The card and the Exact invocation view show every character of a command, with control bytes as visible \u{..} text, and a clipped card says how many characters remain and that Alt+V shows them all. The card ignores Enter for its first 400 ms, while Esc and Alt+X act at once. Cards say when CLIO Coder cannot classify a command's effect or when the effect may not be undone, and name the operator's last typed request together with the job, continuation, peer pane or yolo resume that is asking (ACP clients get it as task in the clio-coder/decision meta).
  • What runs without an ask. An sh -c '<script>' wrapper is judged by its script only in its bare form. The test commands unattended mode runs without asking (npm test, pytest, cargo test and the like) do not match when an argument after -- is an option or a line break separates two words. grep <path> -e <pattern> is not treated as a workspace read.
  • Protected files. Shell commands are judged by what they do: a copy or redirect that creates a new file under a protected name (cp .env.example .env.local) runs while overwriting an existing one stays refused, and a recursive grep, rg, ag, ack or git grep whose walk reaches a protected file is refused with the exclusion flag that lets it run. The grep presence check on secret files is exempt only for the bare ^NAME= pattern. After a read of a secret-bearing file such as a dotenv, a later web_read or web_fetch whose URL could carry data asks under rule secret-read-then-fetch.
  • Text that poses as the host. Escape sequences in assistant prose, thinking text and ask_user questions are shown as text. Text inside host reminders and middleware notes cannot close its frame, and [middleware: lines and system-reminder tags in bash output are neutralized. The safety judge reads the ask reason, the policy reason and the consequence lines, package.json script bodies included, as redacted quoted data, and does not read a job's prompt, a yolo continuation or a file attached over ACP as the operator's own words. A CLIO-CODER.md, CLIO-CODER.override.md or .clio-coder/rules that is a symlink leaving the project is ignored with a diagnostic.
  • Redaction. Tool and approval cards mask JSON-keyed secrets ("api_key": "..."), Bearer values, GitHub tokens, curl -u passwords, Cookie: headers, sshpass -p and docker login -p passwords, ?sig= values, and ASIA, sk_live_, hf_ and npm_ keys, including in worker refusal receipts. A quoted credential that holds spaces is replaced whole, also while it streams. Fleet code-step logs redact secrets and are written 0600, and share archives leave out extension dotenv files.
  • Credentials and links. A runtime plugin gets only the variable it declares or a target's apiKeyEnvVar, whatever provider it names itself after. Anthropic and OpenAI browser sign-in hold the callback port on both IPv4 and IPv6 loopback. Sign-in and other external links open only for https: or loopback http: URLs, and on Windows through rundll32. web_fetch caps timeout_ms at 600000 ms and cleans fetched HTML in linear time.
  • Git. CLIO Coder's own status and diff reads never run a filter driver or git-lfs extension command set in the repository's own config (stock git-lfs excepted) and do not look inside submodule checkouts. Checkouts CLIO Coder itself writes (a reproduce worktree, a fleet merge) still run the repository's filters, so git-crypt and git-annex files land as the repository stores them.
  • Project trust. Opening a repository with its own CLIO Coder configuration shows one card that sums it up (connections, rule counts, hook commands) with Review, Trust all and Open without it. Open without it leaves Project configuration not active · /trust in the session header. /trust opens the same card inside a session, and /reload raises it when a project surface is new or changed.
  • Hardening. Settings files, model profiles and shared archives reject __proto__, constructor and prototype keys. minimatch moves to 11.0.5 (GHSA-g3hv-75wg-m249). telemetry share --profile report anonymizes System One engines, playbook step and command names, endpoint and directory digests and provider tool call ids. Pane handoff briefs are delivered without passing through the pane shell's line editor, report drafts opened in $EDITOR live under CLIO Coder's private state directory, and browser openers start with CLIO Coder's safe environment. ACP session rename requires authentication.

Desktop app and ACP

  • Launchers prove the launch token over a single-use challenge (POST /api/auth/challenge) instead of sending it, and browser launches use a single-use ticket valid for 60 seconds. The launch token is not kept in browser storage or passed on an opener's command line.
  • The launch token rotates on every start of the background app. Launchers and desktop shortcuts read the new one, and a background app installed by 0.7.0 rotates its token on its first 0.8.0 start.
  • Windows opened by clio-coder gui or reopened with a remembered credential open the app directly, and the Reconnect field accepts the #ticket= link clio-coder gui prints. When the open window belongs to a server that restarted, clio-coder gui opens a fresh window. The launcher scripts update themselves on launch after an upgrade.
  • The approval card shows why a call stopped (the safety-net rule or the autonomy level), the size and sha256 digest of a parked write or edit, and the recorded task, matching the terminal card. Setup lists the routes CLIO Coder found, waits visibly on the test message, and offers the same fixes as the terminal.
  • The machine proxy refuses credential routes however the path is encoded, and a malformed percent-encoded path returns 400. A fleet attach polls the forwarded port only after ssh has set up its forwards and fails when the forward exits.
  • ACP: under acp --read-only, acp --allow-tools none, or a client ceiling that is read-only or allows no tools, the stdio MCP servers a client supplies are registered but not started. /poll, /fleet share and /report work over ACP, usage_update carries the cached prompt shares and replay cache breaks, and a worker's merge arrives as a worker_merged notice.

Context, handbooks and memory

The context guide covers compaction and the project handbook.

  • Compaction fails softer. A failed automatic compaction between tool batches no longer ends a run whose next request still fits. Recovering from a context overflow does not send the request a second time, and the retry sends the whole prompt. One message too large for the summarizer no longer fails compaction: the summarizer sees its head and tail, and the session keeps the full text. Compaction never cuts inside a tool batch, does not re-summarize for a few hundred tokens right after a summary, and re-arms after /model.
  • The automatic trigger keeps room for the summary on the route that writes it, so a 200K Claude Opus 5.5 session compacts near its threshold. A summary too large for the compaction model stops before it is sent and says to choose a larger compaction model.
  • /compact instructions are kept verbatim (multi-line, up to 8000 characters) as one operator note across compactions. context with scope budget lists the system prompt's sections and their estimated sizes.
  • context init merges a handbook rule stated twice in different words and checks each rule it adopts from another handbook against the tree, also on --adopt: every rule keeps its source file and line and is sorted as verified, stale, contradicted or unverifiable, with the verdicts in .clio-coder/state/handbook-ledger.json. It also reads Cursor rules, GitHub Copilot instruction files, and Windsurf, Cline and Aider instruction sources, and never writes into their directories.
  • clio-coder context init --verify rechecks the handbook against the tree without a model call, and --apply after it writes a proposal that removes or corrects only the flagged rules. context init --accept [<proposal>] writes a reviewed proposal byte for byte and refuses when the handbook changed since; the TUI accepts one with /context init --accept <id>.
  • Generated handbooks are shaped for workers: generated invariants are capped at 16 rules and 3,000 characters, Tests and Gotchas come first, and sections you wrote keep their place and scope.
  • A repository with no CLIO-CODER.md gets a handbook compiled in the background from its checkers, tree facts and verified adopted rules, with no model call and no write outside .clio-coder/state/; sessions and workers read it from the next session.
  • Work in another of your repositories follows that repository's rules: a dispatch whose working directory belongs to a sister repository gets that repository's handbook (only rules verified against its tree when the repository is untrusted), and the main session gets one reminder when it starts working there. Nothing is written into the sister repository.
  • A run on Codex or Pi reads one set of project rules: CLIO Coder sends its handbook with the rules from the agent's own AGENTS.md or CLAUDE.md that still match the project, and turns the agent's own instruction files off for that run (a Pi older than 0.67.4 cannot, so it reads them beside the rules). Claude Code and OpenCode read their own files beside the rules, so Claude Code keeps the project's permission rules and hooks. fleet.keepPeerInstructionFiles keeps the named harnesses on their own files, and the run record names the files and how many rules were stale.
  • Memory: lesson text carrying host framing tags is rejected, and a lesson's command counts as evidence only once it was seen to succeed. A repository and its subdirectories share lessons, lessons survive orphan branches, a subdirectory lesson does not apply in a nested repository, and a new repository at a reused path starts without the old one's lessons. The memory store keeps working at 500 records or with an invalid record: undecided proposals make room, and invalid records move to records.invalid.json with one notice.

Performance

  • CLIO Coder draws its first frame before it recovers restart worktrees and abandoned runs: with one or two leased workers left from a previous session, startup to loaded domains went from about 1.0 s and 1.9 s to about 0.27 s and 0.21 s. clio-coder run --help answers in about 0.05 s instead of about 0.4 s.
  • Large repositories: session start and @file completion no longer freeze, ls on very large directories is several times faster, and the footer's dirty-state probe gives a large repository more time. One huge or pathological source file no longer disables code_nav (files over 2 MiB are indexed without symbols, each parse is capped at one second), and grep omits matches in lines over 1 MiB with a note instead of crashing.
  • Long sessions: the current position comes from memory instead of re-reading the session ledger on every append, the live budget folds only the messages added since the last update, very large tool results sanitize only the shown prefix, a finished turn in regular mode no longer re-measures every transcript row, and a frame with /settings open takes a few milliseconds instead of more than 100.
  • Streaming: the settled head of a long turn renders once per width, an answer with headings, code fences or rules but no blank lines settles at those boundaries, and an open code fence draws only its open line on each update.
  • Prompt cache: on the openai-codex route the main prompt's pinned layer goes out as its own instructions block, so a handbook edit no longer re-bills the whole prompt. Measured on a changed tail with the real tool set, the cached share went from 0% to 73%. Parallel workers that share a prompt prefix start after the first one streams, at most 15 s later, so they read its prompt cache; fleet.staggerSharedPrefix (on by default) turns it off.

Telemetry

  • clio-coder telemetry cache, the doctor cache row and the exit report lead with the cached share of the prompt for the session and its last turn. When a resumed session's first request parts from the transcript journaled before it, the report names the replay mismatch and the first entry that differs (such as message[7]:toolResult).
  • clio-coder telemetry share --live shares a running session, run or process as a verified snapshot without touching it, and --process <id> shares a process scope. --profile report anonymizes target ids, uses a fresh install id and key for each archive, and previews the names left readable. Older CLIO Coder versions refuse to import process archives and the report profile.
  • A share or diagnostic bundle re-keys each settings fingerprint under a random key minted for that share and carries no real process id or start time, so two shares from one install cannot be linked by them. A target's auth.apiKeyEnvVar stays readable when it holds a variable name.
  • A damaged line inside a call journal no longer stops the session's metering: the journal is retired, a fresh segment continues, and cost shows +?. A killed process's journal lock no longer blocks pruning, and route history reads only the newest 2,000 runs from the last 30 days.
  • clio-coder telemetry inspect shows a session's seal verdict, including a seal that fails verification. A bundle or share of a session where a check fired no longer fails with "holds a line this version cannot read".

Install, upgrade and uninstall

The installation guide and the new HPC clusters guide (a login node with an old Node.js or glibc, a proxy, no internet) cover the details.

  • Installer, npm, pnpm and Bun installs share one lifecycle. Unused versions and runtimes are pruned on Linux, macOS and Windows with a proven keep set: the current and previous version and anything a running session, receipt or graphical service still uses.
  • doctor, paths and upgrade say what an install follows or is pinned to, and how to release a pin. clio-coder uninstall --inactive removes an installer root left behind after moving to another install method, and refuses while a session, receipt or graphical service still starts from it.
  • Uninstall stops CLIO Coder's private pane hosts, removes the exact PATH block install.sh added (kept while other programs share its directory), runs npm uninstall for an npm install (--keep-package keeps it), and closes with what was removed and what was kept, and why.
  • clio-coder upgrade restarts an idle background app once, post-install moves the graphical background service to the active installation, and upgrade --rollback names the exact previous version. After a native-installer rollback, the restored version opens the home the newer one used and names the newer migrations it accepts.
  • A truncated install.sh download does not run, and an interrupted uninstall or prune leaves no install lock behind.
  • The installation guide explains npm's install-scripts warning for @google/genai and protobufjs: both scripts are safe to skip. Packaged docs link to GitHub for repository-only files.
  • Windows: the native clio-coder.exe passes arguments containing &, quotes or %NAME% unchanged from PowerShell, pwsh and cmd. CLIO Coder's managed git shim includes a native git.exe, and git run inside the bash tool goes through it, so plumbing commits such as commit-tree keep the human author.

Fleet, verifier, research and arena

The fleet dispatch guide is the full reference.

  • clio-coder fleet nodes setup <id> [--host ...] [--yes] and setup --all probe a node, install this exact client build when the node lacks it (previewed without --yes) and record the preflight. Preflight matches -dev builds by the same clean commit or build id (clio-coder version --build). fleet nodes tools install <node> copilot-sdk|claude-sdk installs an optional SDK on a node; a run on a node that lacks one fails once and names the command.
  • On a state directory shared by several hosts, the local node and loopback endpoints are counted per host, another host's reservations expire only 15 minutes past their estimate, a dead host's leases are reclaimed after five minutes, capacity denials name the holding host, and session terminate --force releases them. A checkout writer lease records its host and is freed about two minutes after a stopped host's last heartbeat.
  • Under fleet.concurrency: auto in a container or batch job, the cgroup headroom counts anonymous and shared memory instead of reclaimable page cache and keeps a 512 MiB reserve inside the cgroup, and a cgroup v2 CPU quota (cpu.max) caps the local worker count. A capacity refusal names the limit that binds.
  • A worker that hits its tool-call cap keeps its edits, committed to its task branch as a partial result. An edit worker that changed files but reports it could not finish fails as worker_partial_work: its worktree is kept, not merged, under a partial: <task> subject. A worker that reports it is blocked without changing anything settles as no work. Cancelling a worker stops a command it was running, even one that ignores SIGTERM.
  • A dispatch can grant a worker absolute directories outside its workspace in intent.read_roots, readable and never writable. Parallel worktree tasks whose intent.write_roots overlap raise a warning naming each pair, and a coder that needs to write outside its write roots can ask: approval continues the same assignment as a new attempt with the wider roots.
  • A worker runs its project's own check (pnpm or npm test, lint, check, typecheck or build, with plain arguments) or verify <check> in the task worktree it owns without an ask, until it changes a package manifest. A task worktree outside the project links each workspace package's node_modules, so a check that builds a workspace package passes there.
  • A task that names its check as an exact command ("verify by running: ", or "run <cmd> to verify") withholds the merge when the worker never ran that command to a clean exit. Checks you name in the turn that dispatches work (pnpm run <id>, a backticked <id> or verify(check="<id>")) are attached to every task from that turn; only checks the project declares are taken.
  • Host verification runs lint and format checks on the files a task changed, and rejects a whole-repo check failure only when the task's base commit does not fail the same way. Checks run one at a time per machine, across CLIO Coder homes, and the workers dashboard shows waiting for a verification slot; CLIO_CODER_VERIFICATION_SLOT_DIR moves the slot.
  • A fleet loop check that cannot fail (true, :) earns no Tested-by trailer. Nor does a check that ran a test, runner config or package script a worker in the run changed, or a gated check whose runner picks up a test a worker wrote.
  • CLIO Coder says when a worker's change merged onto your branch: the TUI shows a Fleet row <agent> <run> merged <sha> onto <branch>, headless run prints it to stderr, and --json and ACP carry a worker_merged notice. When a detached batch settles after its turn ended, the idle terminal wakes the agent with the results; coordinators no longer poll monitor. A turn that ends while workers still run closes with "Turn ended · N workers running", and when the host refuses a worker's final result, fleet view shows "result rejected: ".
  • A council can seat a different agent per member (a roster or inline agent, or /council --agent); members default to scout and stay read-only. /council --deadline (member_deadline_ms) returns a partial council that names the members the deadline cut off. Under contained yolo an operator /council runs; at default autonomy it asks for plan approval first.
  • /poll <n> <question> asks 2 to 5 independent agents the same question as a one-round vote and shows the distribution, in the TUI and over ACP. --options a|b|c constrains the answer, --models spreads members over targets and models, and --rationale asks each for a short reason.
  • The verifier recipe runs the gate commands its task names in backticks (verify(check="gate-N")), bounded in time and output. A gate gets the admission bash would give the same command, and a --read-only verifier run executes gates inside a sandbox that writes nothing.
  • clio-coder research resume <id> continues a stopped campaign from its journal with the budget carried over. A research --check or --gate can name one run of a sweep (<sweep>/<run>), and an A/A check whose interval spans zero is called inconclusive. Arena copies the untracked and modified files a catalog --check names into each contender's worktree (up to 256 files and 64 MiB). arena run stops on SIGHUP, removes the contender worktrees and exits 129.

Extensions and MCP

  • An api 2 extension tool can declare actionClass: write for workspace writes, and admission honors a runtime tool's declared class (read or write) instead of treating every extension tool as execute.
  • gateway op=describe reports an MCP tool's trusted action class and confirmation rule, the judge sees them when a worker's MCP call reaches it, and tool.decided journal records include confirmationRuleId.
  • An extension runtime's sandbox masks CLIO Coder's whole config directory and the secret files in every directory its manifest declares readable. Empty declared write-root directories (such as .research/) that CLIO Coder created are removed when the runtime stops.
  • The literature library pack 0.2.1 pins cite-nexus-mcp==0.2.2; 0.7.0 pinned 0.2.3, which was never published, so the CiteNexus server could not start. arxiv-literature is 0.6.1, and the hpc and materio plugins moved one patch version. Materio draws its "Next:" band only in repositories with a non-empty .research/.

Fixes

  • A model on the Copilot route that calls a CLIO Coder capability by name (such as monitor after a detached dispatch) no longer leaves the route waiting until the run times out. A Copilot worker that is not signed in fails once instead of retrying.
  • Landing a worktree: true task no longer deletes worker-authored files that .gitignore matches; the receipt names them and the worktree is kept.
  • Closing the terminal, an overwide row or an unexpected error in the TUI runs CLIO Coder's shutdown hooks (draft recovery, telemetry exit status) instead of killing the process.
  • When no runtime directory fits a pane-host socket, CLIO Coder falls back to /run/user/<uid>/clio-coder, $TMPDIR/c-<hash> and /tmp/clio-<uid>-<hash> before failing, and the error names each path that was too long.
  • A second CLIO Coder in the same workspace no longer takes over, and closes, the first one's workers dock.
  • Worker failures are classified from the provider's typed status and message, not stray numbers in stderr; an Anthropic overload no longer excludes the node.
  • A bash timeout says the command outlived its own limit, in human units, and that the shell still works. A long tool call no longer shows "No output from ", and a failing /loop --command or job poll shows its first stderr line.
  • An empty settings.yaml loads as defaults, a settings file that fails to load prints its problem once, and "Edit settings file" can create a project settings file in a project that has none.
  • Headless run prints one answer when the citation check rewrites the draft, prints "reminder to the model: " instead of the reminder's full text, and names an unknown option once. run --json gives every gateway chain step's tool_execution_end frame a durationMs. run --agent records its run as finished when it shuts down for any reason.
  • doctor reports a Copilot model the runtime serves but does not list as information, warns when a user or project playbook replaces another of the same name, notes a Slurm, PBS, LSF or Flux client on PATH, and no longer reads as reporting a missing pane host twice.
  • clio-coder telemetry share --process no longer fails for Codex and Claude Max users on the content-free, structural and report profiles, and a diagnostic bundle can be built for a session that used a Copilot target.
  • A question report whose send timed out no longer posts a second discussion when retried.
  • A command stopped by CLIO Coder's built-in path protection no longer says the project's safety policy blocked it. The safety policy judges a bash call whose working directory starts with ~ in the directory the command actually runs in.
  • CLIO Coder's own worktree, landing and listing git calls no longer follow a GIT_DIR inherited from a git hook or git bisect run. Under a read-only .git, the private snapshot store is pruned to what the kept snapshots reach.
  • Resumed sessions no longer replay a skill the model loaded through a tool as a user message between the tool call and its result.
  • An Esc followed quickly by another key no longer splits arrow and Alt sequences in local terminals, and a mistyped slash command left in the composer no longer turns the next command into a prompt.
  • A sandboxed code step that times out and a sandboxed MCP server that is closed get SIGTERM before SIGKILL. A state lock is removed when its owner record cannot be written (full disk or quota).
  • web_fetch decodes HTML entities once instead of twice. clio-coder --help lists clio-coder gui. library list names the installed version beside an available update. A read-only agent's validation message names only the offending tools. A dispatch plan card's task preview keeps the task's line breaks.
  • After a tool call the status no longer names the previous request's model, the stalled-turn check no longer reads "Right now I'm" as an announced action, the overflow notice says when CLIO Coder's own output-budget guard refused the request, and the headless yolo halt notice counts the tool call that crossed the cap.
  • A call journal whose first line is damaged is set aside and journaling continues, a poll job's deadline wake is announced once, the pane event stream backs off when the pane host drops the subscription, and report drafts no longer mask a target name inside copilot-sdk or github-copilot.
  • The desktop app keeps Review and Details in the session header at 1400 px and labels the report dialog's credit choice with what you chose.

Internal

  • pnpm run release:next is one resumable command for status, rehearsal and release. It reuses a green ci.yml run of the exact commit, asks a typed phrase before every remote write, records npm's acceptance so a publish is never offered twice, and can finish a release whose branch moved after npm accepted it. Release notes credit a report's author only when they opted in.
  • clio-coder dev flywheel prints the maintainers' usage headline and ranked backlog from iowarp/clio-metrics, and scripts/report-dataset.ts builds a consented dataset release from report bundles. Neither publishes anything.
  • Typecheck runs on tsrs --fast with a tsc fallback (CLIO_CODER_TYPECHECK=tsc forces it), pnpm run check runs typecheck and Biome as one pre-commit loop, and pnpm run check:lane runs a lane's gates in one command.
  • pnpm run build no longer empties dist/ (--clean does), so a rebuild in a source checkout keeps the chunks a running process still loads.
  • In CLIO Coder's own checkout, the tracked, hand-written CLIO-DEV.md is the contributor handbook it loads. Prompt fragments declare when they apply, and a hygiene check fails when a fragment names a tool or command its session may not have. pnpm eval:prompts runs the main-agent prompt evaluation.
  • Issue forms ask only what happened, and new issues are labeled from the report block or the form's surface and platform fields. The website paints sooner.

Known limits

Sandbox and safety

  • At yolo the safety floor reads any line holding a command substitution as raw text, so a line that quotes a destructive command as data beside $( or a backtick is blocked, including a command sent to a remote host or container (ssh host "rm -rf /var/www/old && echo $(date)"); write such text with the write tool and pass the file. cd "$X" && shred -u <name> is not caught.
  • Under safety.sandbox: required an outward line that leaves the sandbox still trusts what CLIO Coder cannot check: the job script sbatch submits runs on the cluster as you; npm publish and pnpm publish read the package's .npmrc; an ssh host alias or a DNS name can name this machine; a bare-name push remote and an input file are checked once, before the command runs; and a config or program named by a variable CLIO Coder was started with (KUBECONFIG, GIT_SSH_COMMAND, DOCKER_CONFIG, GIT_CONFIG_GLOBAL) is not checked against the writable trees. A host given as an IP address, any scp, and any option missing from a CLI's short list keep the line inside.
  • The main session's sandbox shares the host's /tmp. It hides the secrets CLIO Coder knows to look for there, such as Kerberos ticket caches, but other files in /tmp stay readable and writable to a contained command, including files that programs on the host later load. A Kerberos cache that kinit replaces while a command runs is readable to that command.
  • A secret file inside a wholly untracked directory that the workspace secret scan reaches only after 20,000 entries stays readable in the sandbox; clio-coder doctor warns when the scan stopped at that limit, and a session does not.
  • A fleet action step that is not a check, a gate or a commit runs as you outside the sandbox, even when it runs code a worker wrote.
  • The stdio MCP servers an ACP client supplies start outside the sandbox, as you, unless the session is read-only or allows no tools.
  • The sandbox does not mask macOS keychain or Application Support credential stores, the macOS sandbox cache is unverified on hardware, and whether renaming a writable parent directory gets past the macOS sandbox's path masks has not been tested.

Store, reports and sharing

  • The project store's local backend lives on one host: a worker on a fleet node sees that node's own store. put copies bytes rather than linking. The clio-core backend is opt-in, experimental and keeps no blob versions. The store has been exercised on Linux only.
  • run_script records store provenance only for the inputs a call declares, as <tag>:<name> or the path store get returned; a store file a script reads without declaring it is not recorded.
  • A diagnostic bundle is shared only from a shell with report --share or report send <id> --share and an authenticated gh; /report in the TUI saves one with the report, and over ACP one is attached only when the client allows it through a permission request.

Terminal and desktop app

  • A fifth clio-coder in one folder runs without panes until another exits. Per-launch pane hosts are verified on Linux only.
  • A fullscreen copy of Korean text wrapped within a few characters of bold or code markup can gain a space inside a word.
  • While an answer streams, a long tight list (items with no blank line between them) or text with reference-style link definitions is not settled early and re-renders whole on each update until the answer ends.
  • A machine attaching to a 0.7.0 node reports that the node did not answer rather than a version mismatch. After the desktop app's server restarts, a browser window without a remembered credential needs clio-coder gui again. A launch ticket stays in the browser opener's command line for up to 60 seconds.

Headless, loops and providers

  • When a project's settings define targets, headless run with no saved chat route borrows no route at all, neither your saved targets nor a detected login, since the project chose its own; pass --target <id>.
  • A command job waits on several conditions only when the agent lists them in its also field; CLIO Coder does not check that every condition you named is there, and /loop --until takes one condition.
  • On the openai route the system prompt still goes out as one instructions block, so a change below the pinned layer, such as a handbook edit, misses the prompt cache for the whole prompt; only the openai-codex route splits it.

Fleet, handbooks and research

  • Work in a sister repository that has no CLIO-CODER.md gets no compiled handbook for that repository.
  • Claude Code and OpenCode always read their own instruction files beside the rules CLIO Coder compiles, so a stale rule in those files still reaches them; CLIO Coder names the files and how many rules are stale.
  • A research campaign tries one candidate per iteration and has no parameter sweeps, and it refuses a check whose run directory is not committed. An arena contender gets the untracked and changed files a catalog check names; any other file a check reads must be committed.
  • Delegation from clio-agent to CLIO Coder was not qualified for this release; clio-agent's own runtime failed before delegating.

Install and platforms

  • Uninstall keeps a data or cache directory set with CLIO_CODER_DATA_DIR or CLIO_CODER_CACHE_DIR when it carries no .clio-coder-root marker and is not named clio-coder, or a data or cache directory under CLIO_CODER_HOME that holds files CLIO Coder did not create, and then exits 1.
  • On Windows, npm and pnpm global installs still launch through npm's clio-coder.cmd shim, where cmd.exe interprets & and %NAME% in arguments; the installer's native launcher does not. The arm64 Windows launchers are built and pinned but have not run on arm64 hardware.
  • Pruning and uninstall on macOS are verified by unit tests only, and process discovery there reads command lines without working directories.