Repository navigation
v0.57.2
v0.57.2
A patch release with fixes for three reported issues, a large cut in dead-code memory and cold callgraph build time, and faster, quieter module restarts for daemon users.
The OpenCode 2 footer no longer sits on "AFT starting…" (#334)
The OpenCode 2 footer showed "AFT starting…" whenever the code-health counts were missing, and they stay missing until every health check has reported at least once. In the reporter's project the dead-code check never reported, so the footer claimed startup for the whole session while AFT was running normally.
The cause was a durable failure record in the callgraph store. The file watcher resolves symlinks to their real location, so a symlink inside the project pointing at a file elsewhere reached a callgraph refresh as a path outside the project. The store recorded that as a store-wide failure, and nothing ever cleared the record, so dead-code stayed unavailable for that project until the store was deleted by hand.
A file that really lives outside the project is now skipped for that refresh and reported in the log. A path that cannot be resolved at all is still recorded, because it could be a project file under another name, but the record now clears itself once every indexed file matches disk, so stores that already carry it recover on their next refresh. The footer says "AFT starting…" only until the first status arrives; after that it shows the counts it has and ? for any it does not, for example AFT E0 W1 | D? U4 C5 | T6.
Editing with validate_on_edit: "full" no longer blocks status (#334)
Without the subconscious daemon, AFT serves requests on a single thread. With validate_on_edit: "full", every edit ran the project's type checker on that thread for up to 30 seconds, so status requests and background-completion polls queued behind it and timed out. The reporter's session logged 33 status timeouts.
The type checker now runs off the request thread. The write, formatting, syntax check and rollback keep exactly their previous order, and the edit's response is byte-identical to before. While an edit is being checked, status and completion polls are answered; any other request, including another edit of the same file, waits for the edit to finish, so edits stay strictly serialized.
No permission prompt for your own session's bash output (#333)
When a command's output is long, AFT writes it to a file under its storage directory and points the agent at it. Every task gets a new directory, so an "always allow" answer never matched the next one, and a session that read its own output with cat stopped on an external-directory prompt. For unattended sessions that meant a stall.
Reading your own session's task output files no longer prompts, through read or through bash (cat arguments and < input redirects). The decision is AFT's exact check that this session owns this file. Other sessions' output, any other file in that directory, and any write, redirect onto, copy or delete of these files still prompt.
This also closes a gap in the previous read exemption on OpenCode, which matched on the path's shape alone: with restrict_to_project_root off, another session's output, or any file placed at a matching path, could be read without a prompt.
Dead-code scans use far less memory (#330)
The dead-code scan copied every dispatched method name of a language into a separate set for each file of that language. It now shares one set per language, which the callers only ever needed to test membership against. Results are identical.
Measured on a 37,358-file corpus across four alternating fresh runs, peak RSS fell from 7.03 GB to 2.2–2.5 GB, and the dead-code phase's own allocations from +4.85 GB to about 4 MiB.
Cold callgraph builds are no longer quadratic
A cold build removed each file's previous rows before indexing it. On a fresh build there are none, but with the table indexes dropped for bulk loading, every removal scanned whole tables. The removal is now skipped for files not yet built in the current run, and the finished database is unchanged.
| files | extraction before | after |
|---|---|---|
| 5,000 | 81 s | 13 s |
| 10,000 | 364 s | 32 s |
| 20,000 | 2,092 s | 194–277 s |
Faster module restarts (daemon users)
When the subconscious daemon restarts the AFT module, it waits for open requests to finish, and until now every restart hit its 30-second limit. AFT now closes background-completion streams at once, hands long wait: true bash calls off to background tasks rather than killing them, and answers pending permission asks and deferred calls immediately. A restart measured about 1 second instead of 31.
During a reload, tool calls now wait for the module to come back, up to the call's own deadline and at most 45 seconds, instead of falling back to running bash on the host. This covers routes that were already open when the reload began, where a refused request had been treated as "module down" straight away. A request that may already have reached the module is still never resent.
This release uses subc protocol 0.23 and needs subconscious daemon 0.17.20 or newer.
Other fixes
- Login-shell PATH refresh helpers are reaped instead of lingering as zombie processes (#332).
- After a rejected status-holder bind, AFT retries with exponential backoff up to 5 seconds instead of retrying immediately (#331).
- The gh shim accepts
gh issue close --reason "not planned", the spelling upstream gh documents, instead of refusing it and accepting onlynot_planned. - Every foreground bash abort outcome is now logged.