v2.2.0
Built by CI from this tag on clean runners. Verify with the .sha256 next to each asset.
What's new in 2.2.0
-
The store's own repair could lock it for everyone, and its log could grow without bound. Opening the store used to repair its search index by deleting the whole thing and rebuilding it one row at a time, inside a single held write lock - on a machine running more than one session at once, a second open could re-trigger the same rebuild before the first one finished. Separately, nothing capped the size of the write-ahead log file that sits beside your store: one was measured at 3.4 GB next to a 75 MB store. Both are fixed. The repair is now one transaction that touches only the rows actually missing (falling back to a full rebuild only when the index is genuinely wrong, not merely behind), and every time the store opens it caps that log file at 64 MB and gives it a chance to checkpoint back down.
-
A new check catches a forgotten step, not just a wrong one. Every check before this could only catch text that was written somewhere - a forbidden word, a missing line. None of them could catch something left OUT, because forgetting leaves no fragment to look for. The new
requirescheck kind carries a trigger (the exact command or tool it watches, which has to be one of the things the rule is already bound to) plus a set of acceptable answers; a call that reaches the trigger without giving any of the answers is refused. It can never bind to "always", because "always" names no specific command or tool for the trigger to compare against. -
Deleting or overwriting a protected file from a shell command used to slip straight through. A rule guarding a file only ever caught a direct edit made through your assistant's own edit tool. Doing the same damage from a shell command -
rm,git rm,truncate,sed -i,tee, a redirect (>or>>), or amv/cplanding on that file - was never even looked at. All of those now count as a write to the file, exactly like an edit does, so the same rule refuses them too. -
A rule bound to a tool's own name is now actually watched when that tool is called. A rule bound to, say,
Agent,Artifact, orSendUserFileused to be seen only along one narrow internal path, so it stayed effectively invisible unless it was also pinned to fire "always" as a workaround. It is now served the same way any other rule is, the moment that tool is called. -
Two binding targets that nothing ever fires are now refused on new rules.
answerandclaim_donelooked like valid triggers to bind a rule to, but nothing in the system has ever actually produced either one - so a rule bound only to one of them stored cleanly and then sat silently doing nothing, forever, with no warning. Binding a brand new rule only to one of those two is now refused at write time;doctoralso lists any rule already stuck in that state, so you know what to look at and re-bind. -
doctorhas a new line watching its own log file, silent for the ordinary case and only speaking up once that write-ahead log has grown past both 64 MB and the size of the store itself - measured beforedoctoropens its own connection to the store, so its own act of checking never throws off what it reports. Also fixed: the--checkoutsand--model-dircommand-line options had swapped help text. -
verifycan now actually repair what it finds broken. It already checked the event log's own hash chain; it now also checks the derived heads projection and the search index, and two flags its own documentation had long promised,--rebuild-ftsand--rebuild-heads, now exist. Both are safe to run regardless of what caused the drift, because each rebuilds a projection the append-only log can always reproduce losslessly, and neither touches anything unless its matching check actually failed. -
A new example,
teeth_census, lists which of your heaviest rules still cannot refuse anything.doctorhas always reported a single count of how many rules marked costly or irreversible can actually prove themselves; a count alone never told you WHICH ones still can't.teeth_censuswalks the same live store and prints one line per heavy rule, so you get an actual worklist instead of just a number. -
revisecan now clear an item's tags on purpose. Giving it an explicit empty tag list used to be refused outright, on the assumption an empty list must be a mistake, so there was no way to deliberately remove every tag from an item. An explicit empty list is now accepted as exactly that: a deliberate clear, the same convention every other field onrevisealready follows. -
The README and setup guide now describe all of the above in plain language, and the tool counts they quote (sixteen tools, ten notes seeded into a brand new store) are counted directly against the code rather than assumed.
If you keep an MCP session running across the upgrade, it keeps using the binary it started with until you restart it. Hooks run fresh each time, so they pick up the new one immediately.
Which download
| asset | meaning search | for |
|---|---|---|
thor2-windows-x86_64.zip |
yes | Windows, the machine your assistant runs on |
thor2-linux-x86_64.tar.gz |
yes | Linux, same |
thor2-linux-x86_64-plain.tar.gz |
no | servers, a NAS, a container |
Each one is a bundle, not a single program. Version 2 is several small
programs that work together: install sets everything up, doctor tells you
whether it is healthy, and the rest run in the background once installed.
What is NOT in the box
- No language model of any kind. Nothing calls out to an API, nothing needs
a key. Meaning search needs a local model file (about 235 MB) that you supply;
nothing downloads itself. Without it, search falls back to matching words and
keeps working - it does not break. - Windows: you need the Microsoft Visual C++ Redistributable
(MSVCP140.dll,VCRUNTIME140.dll) andDirectML.dll, which is already on
Windows 10 1903 and later. If a program refuses to start, install the VC++
redistributable first.
Install
Unpack everything into a folder where it can stay - the setup writes down where
it put things, so moving the folder afterwards breaks it. Then run install,
pointing it at your assistant's settings file. It backs that file up first and
only ever adds its own entries. Restart your assistant afterwards: it reads its
settings once, at startup, so until you restart nothing you installed is
running. Then run doctor to see whether it is actually healthy.
New here? The README walks through it step by step. Coming from version 1?
Your old notes are not lost - see the README's own note on that; version 1
itself is retired, and its source and docs stay reachable at the v1.0.0 tag.
What has actually been run
Every asset is built and tested by CI on a clean runner: the whole test suite,
plus a separate run with meaning search compiled in, plus the plain server
shape. The same code, built from this tree, ran the maintainer's own store
for hours before this tag: the repaired index heal, the shell-write guard and
the new check kind were all probed against it with the forbidden text in the
probe. The packaged assets themselves were not started by hand before
publishing. If one does not start for you, say so - that is the report worth
having.
Full Changelog: v2.1.1...v2.2.0