Skip to content

0.75.2

Released 2026-11-12. A herdr call or any other program sb runs now ends at its time limit, and a project opened from the page asks its trust question under auto mode.

A herdr command that does not end holds nothing: the call ends at its deadline, and the command is killed behind it. A project opened from the page while auto mode is on asks its trust question instead of being refused at once.

Todo #155, live on 0.75.1: a tower run and an ally run each stood at run-start for 61 and 35 minutes. Their herdr agent start was given 35 seconds and the server heard of its failure only when the herdr process ended by itself, so the workspace’s events waited that long for the next run.

  • The cause. The timeout of a herdr command was Node’s execFile timeout, which sends the program one SIGTERM and calls back when the program has ended. A herdr that does not end on SIGTERM held the call for as long as it lived.
  • The deadline holds. Every herdr command the package runs through herdrRun now ends at its deadline whatever the program does: the call fails as cut off (killed, signal SIGTERM, no exit code, and Command timed out after <n> ms where it said Command failed), as a timeout did before, so a start that timed out is still taken for one that may have started pi, and a pane run that timed out for one that may have been typed.
  • The command is ended behind the call. A herdr cut off gets SIGTERM, and SIGKILL two seconds later. On macOS and Linux it runs as the leader of a process group of its own and both signals go to the group, so what it started ends with it; on Windows they end the herdr process alone. A herdr that exited by itself and left a child holding its output is told by its own exit status at the deadline, as before, and what it left is not signalled.
  • The socket too. A request on Herdr’s socket (herdrCall: the listings, pane current, report-metadata, the dashboard’s snapshot) had an idle timeout, which every piece of an answer renewed. It is a deadline for the whole answer now, so a Herdr that keeps sending pieces of a frame it does not end fails as timeout in time.
  • The other programs too. The same deadline holds for every other program the package runs with a time limit, each with the time it had: the pane reaper’s herdr, git and lsof (so a program that does not end no longer holds the sweep lock), the git of the train checks, the ps readings of the process table, tailscale, the macOS firewall reading, the clipboard command, and the file manager’s opener, which is ended alone so that the file manager it started stays. The pane balance helper’s herdr calls had no time limit at all, so a herdr that never ended kept the helper and its tab’s lock; they have 10 seconds.
  • Programs run synchronously, and git by its found path. A program the package waits for in place (ps for a start time, git in the train guard, the train commands and the link allow-list, lsof for a working folder, scutil and tmutil on macOS) had a time limit that sent SIGTERM and then waited for the program to end, which blocked the whole process for as long as a program that ignored it lived; the limit sends SIGKILL now. The process-hygiene guard started git by its bare name and with the old timeout: it finds git on the absolute PATH folders like every other program, with the deadline (5 s).

Desk #51, 11/11: a desk PM who opens a project from the GUI while auto mode is on got a session without the project’s .pi resources, because pi’s trust question for the new pane was answered “not trusted for this session” at once (auto mode’s D3: nobody is there).

  • A project opened from the page asks its trust question. A pane started by POST /api/open/base carries a person’s intent, so under auto mode its question is asked as usual (the GUI, or the terminal when no GUI answers), as with auto mode off. Every other pane keeps D3’s answer. The intent is the sb server’s own, in its memory only: before pi starts the server lists the pane with the folder it starts pi in, and takes it off when the open’s start and join end, however they end. The asking pi asks the server over the control socket (open-intent, with its own pane id and folder) and takes only the server’s yes; nothing in the request or in the pane’s environment can add a pane to the list, and nothing is written to or read from disk for it. open/member and open/main and the POST /api/open/base request itself are unchanged.
  • When the server cannot say. No sb server, one that does not answer within 10 s, an older one (it does not know open-intent), and one that restarted while the project was opening (its list is new) all give D3’s answer, as before this release: the session opens without the project’s .pi resources, and auto mode’s return list shows the refusal. Open the project again.