Repository navigation
Releases: ap9000/toolroll
Release list
Toolroll 0.9.83
- A folder that doesn't answer can't freeze the console. A disconnected
drive, an iCloud-synced Documents folder or a pending macOS privacy prompt
used to stall the whole console at startup. Folder reads now run in a
separate, time-limited process: the console keeps answering, and the one
page that needed the folder says it didn't answer. - Projects come back by themselves. A saved project whose folder was
away when Toolroll started connects as soon as the folder returns, with no
restart. It reconnects only to the same folder it was saved as, and a
project you remove stays removed. - Safer project paths. A project's access is decided from its real,
resolved location, never from how its path is spelled.
Install: npx toolroll up · npm i -g toolroll · brew install ap9000/toolroll/toolroll — https://toolroll.dev/install
Toolroll 0.9.82
- A failing nightly holds your releases. Turn it on with
toolroll release nightly --github(your password). When a lane of your
project's GitHub nightly fails on main, every deploy, the merge and the tag
of a release wait until a later nightly passes that lane, and Needs you
says which lane and why. A release whose own pull request re-ran that lane
after the failure, with the same CI files, goes through. A nightly that
can't be read gives a warning, never a pass. - Every run and chat turn records the model and cost the provider
reported: the exact model id, provider turns, cache-aware tokens, and
cost, with API dollars, subscription usage and unknown kept apart (unknown
is never shown as zero). - Evals (groundwork).
toolroll evalsruns repeatable test tasks in
throwaway worlds, graded by a separate checker process the agent can't
reach. Ten starter tasks ship as drafts; real comparison runs stay off
until they're validated. - CI: required checks report under their exact names on every pull
request; a slow git config read now says it timed out instead of blaming
the project's config.
Install: npx toolroll up · npm i -g toolroll · brew install ap9000/toolroll/toolroll — https://toolroll.dev/install
Toolroll 0.9.81
- The release proof works after the merge. GitHub empties a CI run's
pull-request link once the pull request merges and its branch is deleted,
so 0.9.80's tag could never prove its checks and wasn't published. A run
with no link now stands only when its branch has had exactly one pull
request, ever, and that pull request merged into main. 0.9.80's changes
ship in this release.
Install: npx toolroll up · npm i -g toolroll · brew install ap9000/toolroll/toolroll — https://toolroll.dev/install
Toolroll 0.9.79
toolroll releaserides out a short network failure instead of
stopping. A read from GitHub or git (gh api,gh pr list,
git ls-remote,git fetch) that fails for a passing reason (no
connection, a name that didn't resolve, a timeout, a 5xx, an answer cut
short, GitHub's secondary rate limit) is asked again with backoff for up
to about three minutes, saying why once; then it stops with the original
error. A definitive answer (404, 401/403) is never asked again. A merge or
a tag is never sent twice blindly: after a lost answer the release reads
GitHub to learn whether it happened, and asks again only when it didn't.
When main's branch protection can't be read, the release now says
"Couldn't read GitHub's branch protection" instead of "main's protection
doesn't hold", and still stops.
Install: npx toolroll up · npm i -g toolroll · brew install ap9000/toolroll/toolroll — https://toolroll.dev/install
Toolroll 0.9.78
- Toolroll says when it is restarting. The worker and console now record
when they start, keep a heartbeat every 15 seconds, and record when they
begin stopping and when they have stopped. While one is stopping it takes no
new work,/healthzanswers "draining" at once, pages say "Toolroll is
restarting", and a new start waits only until the old one has finished
stopping instead of a fixed window. A worker that stopped cleanly never
holds its projects. A second liveupis still refused. - The database is copied every few minutes. Besides scheduled backups,
the worker copies the database online every 5 minutes (change it, or the
folder, in Settings → Backups), checks each copy and keeps the newest 24
and one a day for a week. It never holds up the console or the worker. A
deploy uses the latest copy when it is recent and matches the database
exactly, instead of making a new one. Restoring stays a manual
toolroll restore. - See where the time went. A task's page has a "Where the time went"
section under Details: when each part of its release check started and
ended, and each step of its deploys, including what a deploy waited for.
Console pages that take over a second keep a short record of where the
time went, which an instance operator reads on/health. Only page names,
step names and reasons are kept, never addresses or form contents. - A crashed worker is noticed in a minute, not three. Workers check in
every 15 seconds and are treated as gone after a minute of silence. A
project lease is never taken for longer than a minute. - A release's version bump alone no longer owes the upgrade path. Toolroll
now decides from both commits' verified files that package.json and
package-lock.json changed only in the project's own version (the check's
own rule); any other change to them still owes it. - The macOS suite runs on the candidate before it merges. Pull requests
and main pushes now run the unit suite on hosted macOS with Node 22 and 24,
in four shards each, joined intonode 22 · macos-latestand
node 24 · macos-latestexactly like the Linux checks.toolroll release
waits for them; main's protection not requiring them yet is reported, not
refused. After the merge, publication waits only for the tag's publish job,
no longer for main's own CI run on the merge commit. The nightly and tag
macOS jobs are renamed so no other workflow shares a required name. - A release is published without waiting for Homebrew.
toolroll release
ends with "Published; Homebrew pending" once npm and the GitHub release are
verified, instead of waiting up to 45 minutes for the tap's checks. Homebrew
is its own state in the release journal (pending, failed or current), and
running the same command again finishes it: it waits for the tap change's
checks, then merges exactly that change, with the checksum still taken from
npm's tarball. A tap already on a newer version is never moved back, checked
again right before the merge. - A release whose checks run outside the sandbox now reruns its own check
after Toolroll's machine fails. Such a release can't carry later commits,
so it used to file without release terms, and a check stopped by Toolroll's
own shutdown, a lost build or a command that never started waited for a
person. Its approval now seals a release check purpose instead: the check
is held to the release's rules (a complete report, no CI standing in for
its units), and only a failure Toolroll itself confirmed as its own
infrastructure reruns, on the same commit under the same approval, at most
twice. Another commit, a changed scope, release check or check access, or
an approval that no longer stands never reruns. It never carries a later
commit. (Schema v138 adds the column; saved scopes are unchanged.) - A deploy no longer gets stuck behind an
upthat won't stop. When the
old service's processes outlive their stop (a supervisor that exited while
itsupignored SIGTERM), the deployment stops them itself, but only
processes proved, by exact runtime path and arguments, to be that service's
supervisor,upor console and worker. Anything it can't prove refuses and
nothing is signalled. - A killed
upno longer blocks the next start for three minutes.up
records each process it gives its worker credential to. A new start that
proves every one of them has exited signs the old worker off and takes over
at once; a second liveupis still refused. upsigns off however it is stopped. SIGTERM, Ctrl-C, its supervisor
dying or its channel closing all end with the worker retired. A stop that
hangs past the worker's grace stops the console and worker outright
instead of waiting for launchd to kill it.- Deployments wait long enough, and say why. Restoring the previous
service, starting the new one and waiting for its project leases now allow
two minutes (past a stale worker heartbeat's one) and name what they are
waiting for. "Current work must finish first" now says what is running and
what to do. - One command puts back a deployment that stopped half way.
toolroll release --recover-deployshows what recovery will do for the
unfinished deployment;--yesdoes it: stops only that service's proved
leftovers, starts the previous service again and lifts the update pause.
It is safe to run again.
Install: npx toolroll up · npm i -g toolroll · brew install ap9000/toolroll/toolroll — https://toolroll.dev/install
Toolroll 0.9.77
-
CI finishes in about a third of the time. The unit suite runs in four
shards per Node version instead of one 14–21 minute job. The required
checks keep their names ("node 22 · ubuntu-latest", "node 24 ·
ubuntu-latest") and pass only when every shard passed on the tested commit
and the shards together ran every test file once, so main's branch
protection needs no change. A flaky shard reruns in minutes, not twenty. -
The release check's real-model journeys start sooner. They run in the
browser lanes as soon as the scripted journeys end, instead of also waiting
for the unit suite; the check's load budget is unchanged. -
An automatic release checks while CI runs. With "Approve automatically
when checks pass" on, the release files its task and runs its check beside
CI instead of after it. Toolroll approves it only once every pull request
check passed on the commit. -
A release asks for your approval while CI runs.
toolroll releasefiles
the release task and asks you right away instead of waiting for GitHub's
checks; after you approve, the release check runs beside CI. The approval
says "GitHub's checks are still running; nothing deploys until they pass."
Nothing is deployed, merged, tagged or published until every required check
passed on the exact commit, read again right before the deploy; if one
fails, the release stops before the deploy. A check that already failed
still stops the release before anyone is asked. -
The console stays responsive while builds and checks run.
toolroll up
now runs two processes: the console (pages, sign-in and approvals) and the
worker (builds, checks, follow-ups and housekeeping). On a copy of a real
database, the slowest console answer during a heavy check fell from about
5–6 seconds to under 0.3 seconds. A worker that crashes is started again
and recovers its interrupted work as a restartedupdoes; a stop still
lets running builds finish first. A running check's progress is saved at
most once a second, and its final result at once.--single-processkeeps
the old one-process layout. -
Console pages open faster and stay quick while work runs. The sidebar,
the Tasks count and the crew list are read once per database change for each
person instead of up to four times per page, and before a page is drawn they
are read on a background thread so the console keeps answering meanwhile.
The chat landing's lists are kept the same way, and the task page reuses its
"behind main" line for 15 seconds instead of asking Git twice per view. On a
copy of a real database: /board 348 → 26 ms, /agents 320 → 4 ms, /chat 905 →
19 ms, a task page 1.5 s → 0.2 s; with the database changing 40 times a
second, pages take 0.27–0.47 s and the console answers other requests in
about 1 ms (before: 0.35 s typical, up to 1.4 s). A page that re-reads after
a live update gets "unchanged" when nothing it shows changed. -
Fixes from the first review of the above. CI's required checks now
judge the shards with the verifier from the base branch, run none of the
change's code, and fail when a shard executed no tests, its counts don't
add up, or it skips tests the base always ran; a required check counts only
from the CI workflow, never a same-named job elsewhere. A release filed
while CI runs can't be approved by anyone until Toolroll itself saw CI pass,
and you're asked only then. A worker that crashes while a removed project is
still finishing recovers that project's work before anything new starts. A
deploy waits until the console and the worker have both exited. A worker or
console that refuses to start again stopstoolroll upinstead of
restarting forever. A check's final progress is kept until it's saved. -
Sandboxed commands no longer hang on macOS 26.5. The fence denies most
macOS system services and, by default, asked macOS to report each denial; on
macOS 26.5.2 about one denied lookup in 70 never returned while that report
was made, so a sandboxednpm ci,npm packor any Node program setting up
DNS could hang forever (a release carry until its 20-minute timeout). Denials
are now made without the report; nothing the fence allows or denies changed. -
The console is fast again. 0.9.76's release-approval setting was read by
walking a project's whole action ledger once per task row, and every page's
sidebar runs that list four times, so each page blocked the console for about
3 seconds (more with tabs open while anything builds). It now reads the
setting rows through an existing index: pages went from about 2 s to about
0.4 s on a real database. Sizing build checkouts every half hour no longer
freezes the console either. -
A release check's result is always saved. The release check's streamed
part lines now carry a tag no Toolroll version misreads as a journey's own
line; an older console counted them twice, built a progress snapshot it then
refused, and the refusal stopped the check's log and result from being saved
(the check read as "unavailable"). A progress update that fails to save can
no longer stop sealing, and a result that can't be saved says so on the run. -
A renamed or dropped CI job no longer hides its failure. Every failed
attempt on a commit is judged before newer runs replace older ones, so a
job a newer run renamed or dropped can't erase a test failure from an
automatic approval. The Windows containment repeat job keeps one name
whatever its count. -
Toolroll decides what a Full release check owes. Before the check runs,
Toolroll works out from its own record of the last release which parts it
owes (units, scripted and real-model journeys, upgrades), seals that, and
tells the check, which runs at least those. Every owed part needs a result,
whatever the check's report says it selected. CI never stands in for a
release's unit suite, and a journey or upgrade run that listed nothing it
ran is no result. -
Missing evidence is unknown, not clean. What passed only on a retry is
sealed in the check's receipt. If a check's report is lost or damaged, its
retries are unknown and nothing approves itself; the receipt's report and
inventory files are checked byte for byte. A check that passed only when
rerun after the approved setup counts as a retry, and the setup rerun only
happens when the check never started. -
Merging checks main on GitHub itself. A release reads main's head and
compares the branch through GitHub's API, never a local ref, and reads
main again right before merging. Releases approve themselves only while
main's branch protection requires branches to be up to date before
merging; without it, a person's release says which setting to turn on.
Toolroll only reads that setting. -
No lazy fetch on any supported git. Protected Git reads (the release's
object reader and extraction, project knowledge and learning, the task
base, release coverage, review screenshots, grants) run through a frozen
copy of the repository's config on every git version, refuse every
network transport and are time-bounded, so an include, a partial clone or
a planted filter can't fetch, run or hang anything. The deployment script
reads a commit's files with no filter or attribute applied. CI's oldest-git
lane now tests git 2.41.0 exactly. -
Main's protection must actually hold. A release now reads main's whole
branch protection and rulesets and counts them only when they require
branches to be up to date, require the release's CI checks, and can't be
bypassed by the account that merges ("Do not allow bypassing the above
settings"; no ruleset bypass for a role, team, app or organization admin).
A person's release names exactly what is missing, and says which new CI
checks main's protection doesn't require yet. -
Deployment reads only verified objects, with none of the repository's
config. The deployment script hashes the commit and every tree as well
as every file against their ids, and runs git on a copy of the
repository's layout with a config of its own, so a corrupted tree, a
config change mid-read or a custom transport helper can't substitute files
or fetch anything. -
An unreadable last release never shrinks a check. When the last
release Toolroll recorded can't be verified, the release check doesn't
run and says so, and the release card's change list reads "couldn't be
read", instead of acting as if there were no previous release. -
Setup recovery needs proof the check never started. The approved setup
reruns a check only when Toolroll itself found the check's program missing
before starting it and the shell said exactly that and nothing else. Any
other failure is the check's own result for a person to judge, and a
release after a setup rerun says why the first attempt failed. -
Dispatch and coding handoffs can't be held up by a project's Git
config. The worktree binding reads Git's registry as plain files, and the
handoff's branch read is bounded and runs outside its database
transactions. -
A release check that's cut short still leaves its evidence. Every
part of the release check (typecheck, build, units, journeys, upgrades)
now prints its output as it runs, each line tagged with its part (and
upgrade version), instead of only at the very end. Each part's end is
recorded with its start time, exit code, signal, timeout and whether it
was stopped, and a failing upgrade version's own log is printed the moment
it fails. Release check 3261 was stored as "exit 1" with nothing but its
header: a signal had ended it, the plane recorded the signal as a plain
exit 1, and the parts' output was still waiting to be printed. A command
ended by a signal, or by Toolroll's own shutdown, now says so. -
No complete result, no pass. A release's Full check counts only with
its valid report (car...
Toolroll 0.9.76
- Releases can approve themselves when they're green. A new per-project
setting, Release approval: Ask me / Approve automatically when checks
pass, is off by default. Turning it on takes your typed password;
turning it off takes one click and withdraws every automatic approval not
yet merged. When it's on, a release task first reads "Checking
automatically" (auto-check), which lets its release check run and
nothing else. Once GitHub CI and the release check both pass on the exact
candidate, it approves itself (auto-green) and the release continues as
after your yes. You're told, not asked. - What an automatic approval must prove. Up to two failed attempts per
CI job, and two failed release-check builds on the same commit, are
tolerated as flakes. Past that it asks you. The change must touch only
allowed paths: product code and its tests, test files undertest/,
docs, the changelog and a version-onlypackage.jsonbump. Scripts, CI,
configuration, dependencies, policy files and test helpers (found from the
tests' own imports) need a person. CI is read again before the deploy, the
CLI switch, the merge and the tag. Anything not green stops the release,
withdraws the approval and tells you. - A red CI after the merge holds publishing. No tag, npm publish or
Homebrew update happens until a person runs
toolroll release publish-ok <task>with their password. - Stricter CI verdicts on every release, yours too. Only checks on the
exact head count. Required checks must come from GitHub Actions, so
another app's same-name success can't hide a failure. A newer run of the
same workflow supersedes its older runs on the commit. - Toolroll's own git on agent checkouts runs against a frozen view.
Every git command the plane runs on a checkout an agent wrote (staging,
committing, cleanup, pool refresh, scouts, planners, coding sessions, page
reads) runs against a private copy of the repository's settings taken
once. Changes the agent makes to them afterwards are never read. - Git settings are denied by default. Only audited config sections and
variables pass. Aliases, URL rewrites that reach remote helpers, empty
filter names andhook.*are refused. Writes allow no network transport.
Local git-lfs installs still work. - Writes are bound to the project's recorded repository. A checkout
whose.gitpoints anywhere else is refused. Before git writes through a
view, every path it could write is walked for links and hard links. Plane
git writes on one checkout run one at a time. On git before 2.48, a
checkout added through the view is pointed at its repository, not at the
view. - A git incident is recorded and you're notified. A swap seen after git
ran is logged and raised as an attention notification. The notification
names the project by Toolroll's own record, never by a path the agent
chose. discover --dirtyreads repositories through the same hardened git.- Database: schema v136 (unchanged).
Install: npx toolroll up · npm i -g toolroll · brew install ap9000/toolroll/toolroll — https://toolroll.dev/install
Toolroll 0.9.75
- Opening a page only shows it. Pages no longer run checks, tidy up or
call out as you open them. Sign-ins, integrations, update checks, storage
and Codex's tools are checked in the background, and Models, Updates,
Storage, Pull requests, Tools, Project setup and the GitHub listing show
their last answer and when it was checked, with a Check now button to
ask again. On a coding session, Review for shipping and the changes
view are buttons, so a link preview or prefetch can't run them. Reading a
checkout an agent wrote never runs that checkout's own git settings. - Reading an agent's checkout can't be raced into running a filter. Git
reads the checkout through a private copy of its settings taken once, so a
filter the agent adds to its git config and.git/info/attributesafter
that copy never runs. - The task card never contradicts itself. One answer to "did the
approved check pass" across the task page, the road, the Tasks list, the
result page and chat. A check whose saved log can't be read is never
shown as passed, and a check whose command was approved again since it ran
says so: "The check command changed since this check; run checks again." - Lead-filed runs nest under the lead on Agents → Live. Runs your own
lead filed sit under its tile. Once its turn has gone, they stay grouped
under a quiet "Filed by lead chat" header. The lead's full screen lists
every task it filed. Only you see what your lead filed. - The lead passes asks to a helper instead of answering for them. "Ask
Maya to …" now reaches Maya even when she seems to lack a tool or the
knowledge for it; she says so herself or asks you first. - A helper's "can't" reaches whoever asked. When a helper can't do
something asked at its desk, its note (or its reason) goes back to the
person or agent who asked, instead of waiting in an inbox. - Database: schema v136 (unchanged).
Install: npx toolroll up · npm i -g toolroll · brew install ap9000/toolroll/toolroll — https://toolroll.dev/install
Toolroll 0.9.74
- Agents → Live: every agent and subagent at a glance. A read-only grid
of everything running, on desktop and phone: what each agent is doing
right now, how long it has run and its latest lines. Subagents get their
own tiles nested under their parent; they appear when they start and show
Done for 30 seconds before leaving. A quiet agent reads Needs you with
a thin amber outline. Click a tile's title to open it full screen (Escape
brings you back). Your own lead chats show as lead tiles. Nothing on the
page acts, and the grid holds still while you look at it. Terminals you
drive yourself stay off the grid; one line links to Live terminals. Only a
signed-in browser can read it: tokens are refused. - Visiting a page starts nothing. Opening Chat, a task, a result or a
project shows the page with a ready composer; your first message starts
the conversation. A retry or double submit lands in the conversation it
started. Link previews and prefetches can't start one. - A cleaner console. One status chip everywhere, framed panels on the
Board, Settings, Knowledge and Projects, and a road on every task (Plan →
You approve → Build → Checks → Ready) built only from what happened.
Attempts show as a timeline and warnings as plain notices. Amber now means
only "waits on you". Built from ReUI's free, MIT-licensed components
(credited in THIRD_PARTY_NOTICES.md). - The old task list is retired.
/tasksnow opens Work, which gained a
state filter (/work?state=), templates (/tasks/new?template=) and keeps
your draft when a filing is refused. - Rerunning a failed release check keeps your approval.
toolroll task regatequeues the same approved commit again instead of
re-filing it, andtoolroll releasewaits for the rerun and uses it. A
changed commit, scope or approval still refuses. - Database: schema v136 (each run's "Show commands" answer is kept for the
live view).
Install: npx toolroll up · npm i -g toolroll · brew install ap9000/toolroll/toolroll — https://toolroll.dev/install
Toolroll 0.9.73
- Carry release approvals when checks aren't sandboxed. A project whose
checks run outside the sandbox (like Toolroll's own release project) can
let later test-only commits carry a release approval:
toolroll release unsandboxed-carry on --repo <path> --as <you> --token <password>. It is off by default; only a person turns it on, and it counts
only for releases approved while it is on. The approval sheet says plainly
that those later commits will run outside the sandbox without being shown
to you first. Every other carry rule stays: tests and docs only, the
400-line, 20-file and 800-line-churn limits, an identical production build,
and main's open nightly failures. Turning it off, or checks that reach
further than at the approval, stops carrying. toolroll releasestops at the gate when the pull request's checks
fail. Before it files the release task or asks for your approval, it
reads the required checks on the exact commit. One that failed or was
cancelled stops the release with the failing job names, so you aren't
asked to approve a commit that can't merge. Checks not started or still
running are named and waited for; if they don't finish within the gate's
limit (60 minutes,--limit gate=<min>), it stops there too. The ci step
still checks every one again before merging.- Chat apps, browsers and password managers are off limits to every
launch. Builds, checks, flows, tool servers and coding sessions can't
read or write where Slack, Telegram, Discord, Teams, WhatsApp, 1Password,
Bitwarden, or the Chrome, Chromium, Brave, Edge, Arc, Firefox, Zen,
Vivaldi, Opera, Orion and Safari profiles keep their data, on macOS and
Linux, under both sandbox versions and in Codex's sandbox. This covers the
folders by name and by real path, links inside them, and a moved profile
or config folder named in the environment. No project setting reopens
them, and those apps' variables (SLACK_, TELEGRAM_, DISCORD_, TEAMS_, OP_,
BW_, BITWARDENCLI_) are removed from every launch; a tool server keeps the
secrets it names. toolroll releaseruns Git safely on the release checkout. The release
used to run plain Git there, so a setting planted in the checkout's Git
config (an include, a hook folder, an ssh command, a proxy, a URL rewrite
and the like) could run a command or send the gh token elsewhere. Now it
uses the repository and GitHub URL from Toolroll's own records, runs Git,
gh and ssh by absolute path with a fixed environment, pins HTTPS settings
on the command line, and allows only the plain settings Git writes itself.
Any other setting stops the release and names it. The checkout must be a
project Toolroll records, with a recorded remote.- Widening actions take your password. Setting the permission default to
Full access, giving a subagent a tool, loosening a tool rule, accepting a
subagent's suggested looser rule, and adding a trigger that brings in work
from anyone (GitHub from anyone, mail from any sender, from the Triggers
panel, a gallery template or a starter kit) now ask for your password (a
signed-in session does under Passwordless). Narrowing needs none. A chat
card, import or template can no longer do any of these; it points to the
page that can. - Approving a release from chat shows the whole release first. A tap
approves a deploy only through the release card: every signed term and
release term, one line each (it says so when later test-only commits
will run outside the sandbox), and the commits since the last release
Toolroll recorded as merged. Continue sends the terms (as a file where the
chat app allows), and Approve is bound to exactly what was shown;
anything changed in between refuses with the new card. It works only in
your own private chat (Telegram or a Slack direct message); a group,
someone else's chat, Discord and Teams are refused. Each such approval is
announced to you, naming the chat app. - Network, writes, check access and sandbox settings stay on the typed
password under Passwordless, and a test now fails if one moves to the
ordinary signed-in step-up. - Launches don't wait on macOS's "access data from other apps" prompt.
Toolroll looks inside other apps' containers only after a 3-second look in
a separate process shows macOS lets it, so a service run by launchd no
longer hangs every fenced launch. While macOS is still asking, the
containers stay denied by name and real path, and the links found by the
last full look stay denied; a look that fails for any other reason refuses
the launch. - The release check ends itself before its time limit, stopping the
parts still running and keeping every log and its report, and a failed
part's log reaches the run's output as soon as it fails. toolroll releaserides out short GitHub network timeouts while a
step waits, asking again until that step's own limit.- No database change: the schema stays at v135.
Install: npx toolroll up · npm i -g toolroll · brew install ap9000/toolroll/toolroll — https://toolroll.dev/install