Known issues

This page lists what does not work as you might expect in the current version, with a way around each where there is one. It is written from the code and from running it, and it is updated as things are fixed.

Local knowledge and personal sync

  • Personal sync acceptance is isolated and synthetic. Knowledge-specific local services, terminal commands, selected MCP authorization, session preferences and desktop knowledge/memory/workflow pages passed the recorded macOS arm64 development and local-package checks, with separately recorded round trips against an isolated circle-hub, the reference sync server. These do not establish a deployed service, business correctness, manual OS pickers or other native platforms. Workflow imports require a compatible pack.json folder and a separate explicit file installation; arbitrary standalone skills are not converted. Existing memory files and skills work unchanged, with no automatic migration or upload. See the current boundary.
  • Verified local-upload knowledge can still be refused when shared to a team. The isolated circle-hub at 410c9c44 returns SHARE_UPLOAD_UNSIGNED for an entry grounded in a local upload: quote verification does not provide the upload signature required for team evidence. Circle retains the personal entry and shows the server’s refusal message and fix unchanged; the desktop share dialog shows them under “服务器拒绝了这次分享” / “the server refused this share” and adds no instruction of its own. Independently qualified team-source knowledge and personal memories have separate sharing paths. The round-trip receipt records the refusal and the explicitly synthetic team-source fixture; it does not establish a real connector or an upload-signing capability.

Install and release

  • A desktop update from 1.10.2 or earlier can stall forever when the runtime cannot stop. Those versions wait for the runtime to close before quitting, with no bound, and the macOS and Linux installers then wait for the process without one either: restart to update says restarting… and nothing more happens, and after a restart the old copy reports update failed: Circle <version> was not installed. Force-quit Circle (Activity Monitor, or kill its process): the already-waiting installer finishes the swap and starts the new version. If the machine was restarted, the installer is gone with it — start the update again from settings. Updates from this release on bound both waits.
  • Updating 1.9.1 to the published 1.10.0 does not print release notes or a cleanup command. The update succeeds and keeps the older copy, but 1.9.1’s updater predates the report and 1.10.0’s installer does not provide it. Read the 1.10.0 release notes; kept copies remain under the installation prefix’s versions/ folder. The current installer supplies a target-release link and cleanup command for older updaters, but that does not change the published 1.10.0 archive.
  • Very old sessions can lose their installed files after several updates. An installation keeps the newest three versions and the one it replaced. It does not track every other open session. Close sessions from older versions before repeatedly updating or reinstalling.
  • Parts of the Windows build still have not been seen in a real console. The release workflow builds it for x64 and arm64 and tests installing it, starting it and a scripted run, and Windows acceptance records what has since been used by hand in a PowerShell 7 console with code page 936 on the source build: startup and the welcome block, typing and the command list, an approval card for del /q, /jobs and the Job-object stop of a detached grandchild. Still unchecked are Windows Terminal’s own window, the mouse, window resizing, esc and the alt+… chords, /copy, the progress it shows on the tab and the taskbar, and the user PATH change in the packaged build. A terminal window that is not a Windows console, such as the mintty window of Git Bash or MobaXterm, may not count as a terminal; use Windows Terminal, PowerShell or cmd.
  • A command’s leftovers on Windows have been seen end to end only where Windows acceptance ran them: a cmd /c start /b grandchild whose launcher had already exited was ended both by a clean exit and by Circle’s process ending. The rest of this row is read from the code. esc, ctrl+b, a timeout, /jobs, leaving and a hook timeout end a command with taskkill /T /F. Circle also puts each command’s cmd.exe in a Windows Job object as soon as it starts and ends what is left in it, so a program started through a cmd that has already ended (cmd /c start /b …) is ended too; a program started before the Job took the shell is found from the process list instead, and only if the processes between it and the shell were still running when Circle looked. Console hosts (conhost.exe) are left to end by themselves. Processes a command leaves running are not turned into a background job on Windows: the command is reported as finished, and what it left is ended when you stop that finished job in /jobs, when the subagent that ran it ends, and when you leave Circle — of these three the acceptance run tried only leaving Circle.
  • The console code page has been measured on one 936 machine, in Windows acceptance. Circle asks chcp once which code page the console uses (the registry’s OEMCP when chcp does not answer) and reads output in it, but output that is valid UTF-8 is read as UTF-8, since many programs write UTF-8 there. The cost was reproduced rather than guessed: the two bytes 0xD0 0xA1, which are 小 in code page 936 and a valid UTF-8 sequence for U+0421 at once, reached the model as С. A command whose bytes really were UTF-8 (chcp 936 >nul & echo 小 on the tested path) arrived correctly. A code page Circle has no decoder for is read as UTF-8. The desktop application’s commands run in a ConPTY, which gives UTF-8 whatever the code page.
  • On Windows the model’s commands run in cmd.exe, not in bash. The rules now sort the Windows shapes deliberately: del, rd, erase, Remove-Item, format, diskpart, cipher, sdelete, Clear-Disk and Format-Volume always ask, as do reg delete, sc delete, schtasks /delete, vssadmin delete and wevtutil cl; cmd /c and powershell -Command are read through to what really runs; -EncodedCommand always asks because nothing can read it; and a Windows path is taken folder by folder, so C:\proj\.env is the credential file .env. tests/approvals-windows.test.ts checks all of this on every platform, by naming the platform rather than the machine it runs on. What is still unproven is how cmd.exe behaves in a real console, in the rows above.

Sessions

  • Going back with /tree does not undo file changes. It changes what the model remembers, not your files.
  • /rewind undoes the text tools only. write_file, edit_file and apply_patch are journaled in the session’s database for the last 40 turns; what execute, the delete tool, an MCP server or another program changed is outside it, and so is a background subagent that writes after its turn ended. A turn that touched a binary or a file over 2 MB is dropped whole rather than half-offered. Tracking: issue #373.
  • /undo does not make the model forget, and does not revert files.
  • auto and accept edits turn themselves off on /new, /fork, /clone, /import and restart; the session falls back to the default_mode saved in the settings, or asks again (manual) without one. read-only stays with the conversation.
  • projects/ in the data folder is mostly not cleaned up. It keeps the messages that summaries replaced, very long tool results, pasted pictures, pictures saved for a model that does not read images, and screenshots, for every project; only command and job output is removed, a day after its run ended. Delete old folders by hand.
  • Every enter in the terminal pauses for a second or two when Circle cannot write the input history, as when history in the data folder belongs to another user. Circle tries again for about a second each time, then keeps the history for this run only. Make the file yours again (sudo chown "$USER" ~/.circle/history) or delete it.

Terminals

  • In Otty a message queued for a Circle pane does not go out when the turn ends. Otty’s prompt queue does not send to agents that report their state through otty state: (checked with Otty 1.6.2), only Circle’s badges and notifications follow the turn (outside the window). Send the message from the queue yourself.

Safety

These are gaps to know about before you trust Circle with a repository or a machine you do not fully control. The complete list is in Security.

  • /yolo also skips the questions Circle always asks, such as rm -rf and force-push.
  • An allowed_commands pattern skips them too for the commands it matches: git * covers a force-push, and patterns match text, not what a command reaches. Keep them narrow.
  • Custom commands can run shell snippets without asking, and a trusted folder’s commands, skills, hooks and instruction files apply at once. Read a repository’s .circle/, .opencode/, .pi/, .claude/ and .agents/ folders, including hooks.json, before you trust it.
  • The credential-file check reads names, not contents. File tools and commands refuse the listed names, but ls and glob show them, and a command that reaches a file without naming it (a script, a variable, a copy under another name) is not refused.
  • A secret can be written to any path the model names. Check the file on the card before you enter the value.
  • An extension that is removed leaves its secrets and data behind. Its entry in settings.json, extension_secrets/<name>.secrets.json and extension_data/<name>/ in the data folder stay, and nothing in Circle lists or deletes them; a token there stays valid until you revoke it at its service. See Extensions.

Subagents and tools

  • Tool calls other than task in one reply run one after another. Only task calls next to each other run together, and each other call asks for its approval when its turn comes. To run subagents side by side, the model can start them with background: true.
  • The diff on an edit_file card assumes its text appears once. When the text to replace appears more than once, the card shows the change at the first place, but the tool refuses such an edit unless it replaces every one. The model is told and usually tries again with more context.
  • An idempotent MCP tool’s earlier result can be given again after something other than this conversation changed the server. Circle forgets a server’s kept results whenever it sends that server a call that may change it, but it cannot see what another client, or the server itself, did in between. The card says when a call is answered from an earlier result and not sent; reject it to have the model ask for the call in another way, or reload the servers to forget every kept result. See Files a tool takes.
  • grep searches for literal text, not regular expressions. Its description says so and points the model to rg in the shell for a regular expression, which asks for approval like any command.
  • The editor bridge is a server with no editor shipped for it. Circle answers MCP on 127.0.0.1 with a token; nothing yet reports your file and selection to it. Write or install a plugin that calls editor_report_file and editor_report_selection, and read <data>/bridge.json for the address and token. Until then /bridge start opens a door nobody is on the other side of, and the four tools answer that nothing was reported.
  • The bridge cannot tell your editor anything. An editor asks for pending diff requests; nothing is pushed at it. A diff the model opens therefore shows up when your plugin next asks, and an unanswered request is dropped after an hour.
  • The desktop application has no bridge of its own. /bridge there says it is the terminal’s. The window already has your files in it, so the state the bridge reports would be the window’s own.
  • Nothing remembers on its own. /memory add writes the line you ask for; Circle does not decide anything is worth keeping, and compaction captures no note. The manual path is the whole feature today, so a session that learned something useful loses it unless you say /memory add.
  • The desktop application reads MEMORY.md but does not write it. /memory there tells you where the file is and shows the exact line to paste; a line is written with the terminal’s /memory add, or by editing the file in the window. The caps are the same either way: 240 characters to a line, and only the first 24,000 bytes of the file reach the prompt, so a long memory file quietly stops being read.
  • The desktop application’s approvals page knows only this conversation’s rules. The rule files - your approvals.json and a project’s .circle/approvals.json - are read by the same policy in both programs, so a deny written in either is honoured in the window and the refusal names the rule. But that page lists and revokes only what a card kept in this conversation: it cannot show the files, write one, or say which layer answered for a call. Do that in the terminal with /approvals.
  • GitHub review threads have no Circle tool in front of them. The built-in create-pr and pr-review skills run the GitHub CLI (gh) as a command, so they need the gh on your PATH, signed in the way gh auth login saves it. Circle has no pull request tool of its own, and the desktop application’s github_* connection tools read a task’s checks and failed logs and publish its draft without gh, but answer no review. The window shows pull requests with the copy of gh Circle installs for itself, which is not on the runtime PATH: on a machine with no gh of your own the card answers while a skill stops. gh in a conversation does not reach GitHub Enterprise unless you configure it there yourself.
  • A pull request read through gh arrives as command output. gh pr diff gives the whole patch in one command result, so a large one reaches the model as the tail of it, the way any long output does. Circle has no per-file pull request diff to read instead.
  • Nobody can type into a running job from the keyboard. send_to_job is a tool, so it is the model that tells a subagent something; the person’s routes to a job that is running are still its approval cards, its question, and stop_job. A message the subagent never reached stays in that subagent’s own queue and is shown in its conversation, so nothing is claimed as delivered that was not.
  • Native web search depends on the endpoint and model. A provider preset is not a guarantee that your model, subscription or gateway supports its search API. Custom compatible endpoints that silently ignore search tools fall back to DuckDuckGo because Circle cannot confirm execution. If native search is unavailable and both DuckDuckGo endpoints are blocked or serving challenges, websearch fails; webfetch can still read a known URL when that site is reachable. Hosted search fees are not included in known token prices and remain unpriced.

Images and screenshots

  • Pasting a picture and screenshot have not been tried on a real Windows or Linux machine. They use PowerShell on Windows, and wl-paste, xclip and the screenshot programs on Linux; the tests run them against stand-ins. Past isolated macOS runs exercised the system clipboard in terminal and desktop development/packaged checks, inspecting image input, stored history and restoration. Those results belong to their recorded binaries and input methods. A menu action or a controlled clipboard event does not establish a trusted keyboard paste; OS PNG re-encoding can change bytes without changing pixels. The terminal’s drawing was stubbed in that test.
  • On macOS a missing Screen Recording permission is guessed from whether other applications’ window titles can be read. When the guess is wrong the picture shows only the desktop. The model is told why that may be when the other windows’ titles are hidden, but not when only the terminal’s windows are on screen.
  • Without app, screenshot takes the main display only on macOS and Windows; other displays are left out. On Linux the screenshot programs take every display.
  • On Windows a minimized window cannot be taken. The model is told to ask you to restore it.
  • A picture sent earlier in the desktop application is lost to a model that does not read images. One pasted, dropped or attached while a model that reads images was in use was never written to a file, so after a switch to a model that does not, that model gets only its name, and the side vision model cannot describe it. Send it again.
  • Only PNG files are scaled down. JPEG, GIF and WebP pictures, and pictures an MCP server returns, are sent at the size they are; an endpoint may refuse one that is very large.
  • After upgrading from 1.0.4, which models read images is known once models.dev is fetched again, within a day unless CIRCLE_NO_MODELS_REFRESH is set. Until then pictures go to every model, as in 1.0.4.
  • A model models.dev does not list is assumed to read images until its endpoint refuses one. That request fails with the endpoint’s words; until Circle quits, the conversation then gives the model the pictures’ paths instead, so send the message again. "images": false for the model under models in the settings avoids the failed request. See Images and screenshots.

Background jobs

  • A process that leaves its process group is not tracked. setsid, a daemon that detaches, or a program that starts a service elsewhere is not part of the job: stopping the job, or leaving Circle, does not stop it.
  • If Circle is killed with SIGKILL, or crashes, its jobs keep running. Find them with ps and stop them yourself.
  • Jobs do not outlive Circle. A reopened session has none running; the note Circle leaves names the ones that were stopped (not after SIGTERM, SIGHUP or a closed terminal window).
  • A background subagent keeps the agent it started with. After /reload, /models or a change of extensions it still uses the old tools and model until it ends; /plan reaches it.
  • The output a dev server prints may not show on its row: many programs keep their output in a buffer when it does not go to a terminal (python3 -u and PYTHONUNBUFFERED=1 help for Python).

Device terminals

  • No serial port, no file transfer. Only SSH and Telnet over the network are in this version; a physical serial console has to be reached through a console server’s network port. There is no SFTP, scp or Zmodem: what the device does is typed at its prompt, never pushed as a file.
  • SSH signs in with a password or one private key. There is no keyboard-interactive challenge beyond answering a prompt that asks plainly for a password, no SSH agent and no certificate authority. A device that needs those gets “refused the connection”; reach it through a jump host you can log into.
  • Telnet is a plain console. Circle offers only its window size (NAWS): it does no terminal-type, environment or authentication negotiation, and never encrypts. A console that insists on an option Circle does not answer may wait; the device sees the refusals.
  • Text is sent as UTF-8. A device on another codepage shows mojibake both ways; there is no way to choose an encoding.
  • A resize reflows the emulated screen, not the device’s memory. When a full-screen program (a vi, a menu) is on the device it repaints itself; a line-mode device that wrapped a long line at the old width keeps its old breaks until it prints again, so a terminal_read right after attaching may show some lines broken where they were.
  • On Windows, terminal_wait without a pattern cannot tell that a custom prompt is back. Windows has no process in front of the shell to ask, so on one of your terminal tabs a wait ends at the prompt only when the line at the cursor ends in $, #, %, > or ❯. The default PowerShell PS C:\…> and cmd C:\…> prompts do; a themed prompt ending in another mark, such as ➜ or ✗, does not, and the wait runs until timeout_ms although the shell is idle. Give the wait a pattern that matches your prompt, or end the prompt with one of those characters. The list is not widened on purpose: a wider one would end waits on ordinary command output.
  • terminal_wait matches a screen, not a byte stream. The pattern is tested against the last 400 lines joined with newlines, so it sees what is on the screen now: a device that printed the answer and cleared it, or scrolls it past the buffer, is gone before it can be matched. Read or wait soon after the device rests. absent and changed read what the device printed since the wait began on a screen of their own, where a clear keeps what it erased; still, text a full-screen program draws and draws over in one burst, or more than about a thousand lines arriving at once, can pass absent unseen.
  • A device that prints with a bare line feed can look staggered. Circle normalises \r\n, but a device that emits lone \n or lone \r at wrap can leave a phantom blank or a short line; terminal_read trims trailing blanks to keep the tail clean.

Slow failures

If your endpoint is slow or never answers, a turn can take a long time to give up. A timeout is retried 10 times, and each try waits longer for the answer, up to 5 minutes, so an endpoint that accepts the connection and then sends nothing takes about 50 minutes. Press esc to stop sooner. An endpoint that refuses the connection gives up within about five minutes.

Desktop application

  • A control can miss its first activation after a drawer closes in 1.13.0. If its tooltip was showing and the press closed the drawer before the pointer was released, the next click or keyboard activation of that control can be ignored. Activate it again; the fix is in #353.
  • Linux file dialogs stay in English without GTK’s Chinese catalog. Cancel, Open, Recent and Home are GTK’s strings, not Circle’s. locale-gen zh_CN.UTF-8 and launching with LANG=zh_CN.UTF-8 LC_ALL=zh_CN.UTF-8 do not translate them when gtk30.mo is missing. Ubuntu installs that catalog with language-pack-gnome-zh-hans; it lives at /usr/share/locale-langpack/zh_CN/LC_MESSAGES/gtk30.mo (Debian often uses /usr/share/locale/zh_CN/LC_MESSAGES/gtk30.mo). Electron initializes GTK before this script runs, so a language change inside the app cannot relabel a dialog the C locale already drew. When the interface starts in Chinese and LANGUAGE is unset, Circle sets LANGUAGE=zh_CN, which gettext honors once the catalog is installed. This check has no gtk30.mo, so a live Chinese dialog was not verified.
  • It is not signed by Apple or Microsoft. macOS asks once whether to open it (System Settings → Privacy & Security → Open Anyway), and Windows SmartScreen may stop it the first time (More info → Run anyway). See Installation.
  • On Linux, chrome-sandbox must be setuid root, including after every update. Where unprivileged user namespaces are restricted, as on Ubuntu 24.04 and later, Chromium’s sandbox helper has to be owned by root with the setuid bit; until then the application stops at start. Replacing the folder, by hand or from the update, drops that bit. The one procedure is in Installation: quit Circle, delete the old Circle-linux-* folder, unpack, then run the two commands. An in-app update of a setuid copy does not start Circle again. It shows the commands in a confirm dialog before it quits, and again the next time it starts.
  • Linux can replace a folder it may write; 1.6.0 and the published 1.7.4 cannot. Check now downloads and checks the archive, then quit and replace swaps the folder. When the folder cannot be written, check now opens the release page and the about page keeps the steps, including the chrome-sandbox commands when the running helper is setuid. Those two releases have no in-app updater, so one manual update is required before later ones can install themselves. Releases up to 1.2.0 do not update themselves on any system; install the newer release over them once by hand.
  • Updating the Windows installation asks for administrator permission, as installing did, because the .msi installs for all users. Declining it leaves the old version, and settings say that the update was not installed.
  • A waiting steering message cannot be sent at once yet. The terminal’s enter on an empty box has no counterpart in the application: the message is read before the model’s next step. Waiting messages can be removed one by one, or all put back in the box.
  • Circle judges the line a terminal tab runs by its best reading of the prompt. It is the text Circle typed since the line last ran, with the values of the secrets it named. After an editing key such as Tab, an arrow or Backspace, a line from the shell’s history, or your own typing on that line, it is the text on the screen from where the typing began, Circle’s or yours. When Circle cannot tell where that was, because you typed on the line before Circle had read the tab, it is the whole line with its prompt: that line is shown to you every time, in every mode, auto included, with no rule to keep, and is refused only when it reads as refused. A program at the prompt that is not a shell, such as an editor, a REPL or a menu, is judged the same way.
  • An approval card for a terminal tab that closes stays open. Answering it types nothing; the call fails and says the tab was closed.
  • Circle in terminal tabs has not been tried in a real Windows console. The checks against real shells run on macOS and Linux; on Windows only the checks against a simulated terminal service run.
  • It refuses to start with --no-sandbox. The application enables Chromium’s sandbox for every child process; the switch contradicts that and crashed the main process with an access violation when the first child process started. It now exits with an explanation instead. See electron#54838.
  • External file access is an exact, temporary text-file grant. The desktop lets the current conversation select one existing regular text file through the native OS picker, with read or read/write access. Tool approval alone does not grant access. The grant covers no parent directory, sibling/new file, symbolic/hard link, credential or protected application-data path, and is not inherited by another conversation or kept after restart. Native external directory/media reads and shell access through that grant are unsupported; an MCP tool’s file parameter can send a granted text file. Workspace and external files cannot share one patch or undo transaction; such a mixed batch is rejected before writing. Revoking access also prevents subsequent file undo. See the grant contract and source path.
  • A runtime that stops loses what it held only in memory. After the runtime process exits unexpectedly, text the model was still streaming, waiting approvals and questions, and file grants are gone; background commands it started may still run and are shown as interrupted. The restart waits about 31 seconds for the stopped process’s session leases to expire. A runtime that stops twice within ten minutes stays stopped until you restart it. On Windows a crash reports 0xFFFF7003 whatever the cause, since no crash handler is running; only the runtime’s error output in logs/runtime.log can tell an out-of-memory stop from another crash. The runtime’s JavaScript heap is capped at about 4 GB by Electron (pointer compression), and --max-old-space-size does not raise it.
  • macOS can stop waking the runtime’s thread pool. The four threads on which the runtime does its file operations, DNS lookups and some cryptography sleep on a pthread condition variable. On macOS 27.0.1 its counters were seen to reach a state in which signalling it wakes no thread, so every such operation waited for ever: Git and file lists never answered and the window said Circle is still working on workspace-service · 39s, counting to the two-minute timeout, again and again. Circle does not prevent it; it notices within a minute and restarts the runtime, which interrupts a turn under way as a crash does. libpthread’s ulock-based condition variables do not keep those counters, but switching to them (PTHREAD_MUTEX_USE_ULOCK=1) makes libpthread end any process that waits on one condition variable with both kinds of mutex, and a standard Node.js build does so as it starts, so Circle does not use it.
  • Workspace grants expire with the application. The files mode lists the folder of the open session again by itself when the folder is trusted; another folder has to be opened again with open folder after a restart. Conversations and pinned input stay in the application’s own data folder.
  • Only the default workspace can move; the rest of the data folder stays on the system drive. Session history, the projects/ offload folders and updates keep growing in the data folder wherever the default workspace lives.
  • Changing the default workspace moves no files. The old folder — including the built-in runtime-home/workspace and its projects/<name>-<id> offload folder — keeps its sessions and stays until you delete it by hand. While the built-in workspace folder holds files the settings page names it; another folder chosen before is not named.
  • A default workspace that is missing at start falls back to the built-in scratch folder, as when its drive is unplugged, and the app keeps resuming that scratch folder after the drive returns until the folder is chosen again.
  • Desktop file undo covers recorded text-tool changes in the current runtime only (the terminal’s /rewind reads its journal from the session’s database and survives a restart). The separate message action previews the paths and requires confirmation; changed revisions prevent restoration. Its in-memory journal is not restored after restart and does not undo Bash/Git commands, external services or historical unrecorded changes. Conversation /undo and /tree keep their separate meanings. See the interaction model.
  • This session’s file-tool history is lost on restart. Each file recorded by a file tool is compared with its version before the session’s first change in this run; those recorded differences start empty after a restart. In a Git repository, this session also includes the uncommitted files the changes card lists, including manual and command changes, and those remain visible after restart while Git reports them. all uncommitted reads the repository’s working tree against the last commit; a folder that is not a Git repository has no such list.
  • Native multi-file saves are not one filesystem transaction. All versions are checked before writes, but a later conflict, I/O error or cancellation can leave an explicitly reported committed prefix. Recovery must keep those committedPaths and retry only the remaining edits after review. External programs do not participate in Circle’s in-process queue; the final revision check and filesystem replacement are not a portable compare-and-swap against an unrelated writer.
  • Developer-loop performance and platform acceptance need evidence from the candidate being shipped. Durable-stream microbenchmarks exclude native input/rendering and do not establish the full 10,000-message/eight-agent interaction targets. A development journey does not establish Windows/Linux packaged behavior, and scripted GitHub transport tests do not establish hosted repository permissions or real Actions results. Run the corresponding native, packaged and separately authorized live checks before claiming those outcomes.
  • Windows shows no count of waiting requests on the taskbar, only a busy bar. macOS shows the count on the Dock icon, and Linux where the desktop supports it. Windows notifications need the Start menu shortcut the installer makes.
  • Some words come from Circle’s core in English in the Chinese interface: slash command descriptions, the shortcut list, error messages and reasons for an approval other than the common ones. The terminal interface is English only.
  • A failed turn’s line lasts only while the application runs. It is shown in the conversation, but not saved with it.
  • Browser snapshots cannot read a frame from another site. Same-origin frames and open shadow roots are included; a cross-origin frame’s contents are not. Open the frame’s address as the main page when you need Circle to read it.
  • Coordinate browser clicks require a current screenshot. Scrolling, changing tabs, resizing, navigation and page changes invalidate it. A target inside a cross-origin frame is refused; open the frame’s address as a main page or take over the browser. Coordinate clicks are not included in recorded scripts.
  • A certificate allowed once is forgotten when Circle exits, and one trusted for good can be reviewed only in browser-certificates.json in the application’s data folder (delete an entry there to forget it). Circle cannot tell when Chrome would refuse to let anyone proceed, as for sites that require HTTPS: Electron does not say.
  • Circle cannot answer a page’s own file picker (showOpenFilePicker and the like) when one of its clicks opens one; the result says so, and you can choose in the browser. Dropping files onto a page is not possible either.
  • On Linux a browser page that moves to another window opens again there. Opening the browser in a window of its own, putting it back in the drawer and showing another conversation each load the conversation’s pages anew in the window they go to, with their history and zoom: what a page held only in memory or in its session storage, such as a form being filled in or where it was scrolled, is lost, while its cookies and local storage stay. A page moved with its view, as on macOS and Windows, was seen to stay blank there. Electron 44.0 to 44.7.0 stacked a view moved to another window under that window’s own page on Linux (electron#54626); Circle now runs 44.9.1, which has the fix, but whether that alone keeps the page showing on a Linux desktop has not been tried yet.
  • In the terminal’s browser a click of yours while Circle acts races Circle’s: there is no layer over the page and no take over. Stop the turn first, or let the model hand you the browser. In the desktop panel the layer takes clicks, not keys: keys you press in the page during an action still reach it.
  • Downloads cannot be paused or cancelled from Circle. In the terminal’s browser a download still arriving when Circle exits is lost.
  • A system download integration can take an attachment before the terminal browser downloads it. With IDM Advanced Integration on Windows, a first navigation from a blank tab to a local HTTP attachment was replaced by an HTTP 204 response. Chrome reported an aborted navigation and started no download; Circle reports the response it received. Opening the site’s ordinary page before navigating to the attachment worked in that local check. Circle does not change the system integration or browser security policy.
  • The terminal has a browser only with Chrome, Edge or Chromium installed, and only in the full-screen interface. CIRCLE_BROWSER names one Circle does not find. The terminal’s browser shows permission requests and the choice of a client certificate to you in its window; the model does not see them.
  • In the terminal’s browser an HTTP sign-in that Circle’s action meets has no prompt for you until the model answers it or hands you the browser; the tab keeps loading meanwhile. A sign-in that a page’s own requests meet (an image, a script, a fetch) is left to the browser, and the model does not see it.
  • A replayed script finds a field without a name by its order among the unnamed fields of its role ({ "role": "textbox", "name": "", "nth": 2 }), as a form without labels gives no other name; a change to the form can move it onto another field. Text next to the field is not used to find it.
  • The desktop browser draws nothing while the screen is not shown, as over a remote desktop nobody is watching: a page’s animations do not end, so an overlay that fades out stays and Circle’s clicks find elements covered or time out. Keep Circle’s window shown while it uses the browser.
  • Chromium’s developer tools take the page’s debugger while they are open. Circle’s browser tools wait until those tools close, then attach again and need a fresh look at the page. Breakpoints set in those tools are not kept.
  • Secrets and saved sign-ins are stored unencrypted. secrets.json, extension_secrets/<extension>.secrets.json and, in the desktop application, desktop.secrets.json (the GitHub connection’s saved sign-in) rely on your user’s file permissions, by the owner’s decision: no keychain, libsecret or DPAPI. Session-only GitHub storage is an explicit choice that writes nothing.
  • A secret’s value is hidden wherever it shows in output, even inside other text. A password that is a common word, such as admin, turns that word into %NAME% in tool results, also inside a longer word, which can confuse the model and tells it where the password appears. It stays as written where it is also a plain variable’s value, or where it stands as a word in what you or the model wrote in the conversation, since the model knows it already. A secret value Circle put into an MCP server’s header is replaced in what that server says even then, also in its tool descriptions and instructions.
  • A model that writes its tool call as text in its thinking ends the turn with “model returned an empty response”, as step-3.7-flash sometimes does. Circle does not resend it on its own; send “continue” to have it try again.
  • In the desktop browser, a page’s prompt() is answered through a request to its own address. A page whose content security policy forbids requests to its own origin, or a page without an origin (about:blank, data:), gets no answer: prompt() returns nothing there. Circle takes over Electron’s private dialog event to show dialogs in the tab; a test checks alert, confirm and prompt on every Electron upgrade.

CI and flaky checks

These checks have failed now and then on CI. Each is tracked in an issue that holds the evidence and decides whether it is a fault in Circle, a check that measures unreliably or a check that is not needed (AGENTS.md). Until that is decided, such a failure is rerun only with its issue named on the pull request.

  • A check job can reach its 20-minute limit in the merge queue (#348). check (macos-15) and check (windows-latest) did once each on 28 October, and GitHub kept no log of either. The same changes passed in other runs. Not classified; the cause is not known. Since #361, npm ci and the suite stop at limits of their own inside the job’s, so a stall there fails its step while the job keeps its log and the suite’s output. check (windows-latest) now works on a Dev Drive with TEMP on it, which took about a third less time in the measurements on the issue. ReFS has no 8.3 short names, so the suite no longer runs under the short spelling of the runner’s TEMP; the Windows short-name test makes its folder in that TEMP on the system disk.
  • Windows editor journey: UNKNOWN: unknown error, open …/editor-main.ts (#331). In the journey’s own simulated outside edit rather than in Circle’s save: once on a pull request in October, and again on 2 November in package-other-platforms (windows-latest). Classified as a needed check that measured unreliably (medium confidence). Since #332 the journey waits for the save to finish before that edit. Why Windows answered UNKNOWN is not known. Since #364, a refused outside write records the error’s code, errno and system call, and on Windows the processes that have the file open. On 2 November that list was empty, but it was read only after a new PowerShell had started and compiled its lookup, seconds after the refusal. The lookup now starts with the editor journey and answers a refusal at once, and the record says how many milliseconds after the refusal the answer was in (holdersWithinMs). A save in the editor also waits out UNKNOWN as it waits out EBUSY.
  • Windows, real-Chrome tests: a test’s own loopback page did not load (#365). Once each, within 15 seconds on one runner on 29 October: browser-chrome-snapshot-clicks got ERR_TIMED_OUT from its own 127.0.0.1 server, and browser-dialog-world reached its fixture deadline on its first navigation. Both passed when run again. Not classified: the run does not show whether Chrome’s request reached the server. Since #369, the loopback servers of real-browser tests record their connections, requests and answers, and a failure prints them, so a recurrence shows whether the request never arrived, arrived unanswered or was answered in time. The issue closes once a recurrence is classified with that record, or after a few weeks without one.