Releases: alexeyw/knotwork
Release list
v0.8.0
Knotwork can now be called by the automation app you already use, and a run nobody is watching is bounded.
Upgrading from 0.7.x is an ordinary in-place update. The signing key is unchanged, so unlike the 0.7.0 release this one does not ask you to uninstall anything.
Another app can ask Knotwork to run a pipeline
Tasker, MacroDroid, or a shell script over adb can now ask Knotwork to run one pipeline you nominate. The other app decides when, using its own permissions and its own conditions; Knotwork does the language-model part of what. It complements an automation app rather than replacing it.
It is off by default and opens only through a consent dialog that spells out what you are agreeing to. Even switched on it does nothing until you bind exactly one pipeline — and that binding is an allowlist, not a fallback: a request naming any other pipeline is refused rather than quietly redirected. Your tool approvals still apply exactly as they do to the app's own background runs; an external call asks for a run, it does not approve what the run then wants to do. Every request that arrives, accepted or refused, lands in a readable journal with the reason in plain language.
Android does not tell an app who sent a broadcast unless the sender opts in, which automation apps do not — so the callback address is taken at face value, and that is why the callback carries only your own request id and a status, never what the run produced.
The smallest call is two keys: which pipeline, and what to say to it. Worked Tasker, MacroDroid and adb examples are in the contract documentation.
Runs that nobody is watching now have limits
A background run with a cloud provider configured spends your own API key, and until now nothing stopped one that started going in circles. Runs now carry step and token ceilings counted across the whole run tree — so a nested sub-pipeline cannot start a fresh allowance, and neither can answering a background approval hours later, which is the case that actually leaked. Background runs get a tighter token ceiling than interactive ones, and both are adjustable.
A separate detector ends a run that keeps repeating the same work without getting anywhere. Either way the run says why it stopped, in words, and reads as a guard doing its job rather than as a broken automation.
Also in this release
- Knotwork now installs on Android 14 and 15, not only Android 16. Two features still need Android 16 and fail softly without it: calling functions other apps expose, and one platform hardening on the external-automation receiver. The hardware requirement is unchanged and is the one more likely to bind: a local model still needs roughly 2 GB of free RAM.
- A prompt can travel as a Markdown file — export one, send it to someone, import it back. A prompt file supplies wording only: it cannot add tools or steps, and a file that asks for them is imported as text with the request named.
- A thinking model's private reasoning no longer arrives as your answer. It was reaching the chat, the stored history, and the parser that reads structured replies.
- Values in the run console can be copied from the tab you are actually looking at.
- A short catalogue of the decisions that constrain contributions now ships in the repository, for the cases where the obvious change is the wrong one.
Which file to download
knotwork-0.8.0-full-release.apk— the standard build. This is the one to take unless you have a reason not to.knotwork-0.8.0-foss-release.apk— no proprietary dependencies, no crash reporting.knotwork-0.8.0-full-release.aab— for the store pipeline, not for sideloading.
Verifying what you downloaded
SHA256SUMS.txt covers all three files. The APKs are signed with:
C=CL, CN=Aleksei Volodin
SHA-256: e50c8aa47c38c808e449c87dbcd4ab9d0d810bcd8ca9d33fd0ce83d492c81651
Check it with apksigner verify --print-certs <file>.apk. A build signed by C=US, O=Android, CN=Android Debug did not come from this release.
Pre-release
This is still a pre-release. Storage formats, the pipeline JSON schema, the Kotlin public surface and the settings layout can change between minor versions without a migration path — with one deliberate exception: the external-automation contract's action, keys, statuses and refusal reasons are frozen as of this release, because profiles written against them live in other people's apps.
Full details, including everything not summarised here: CHANGELOG at this tag.
v0.7.3
Long-term memory works in a released build. It did not, in any of them — not in 0.7.2, not in 0.7.1, not in anything published before.
What was broken
Saving a message to memory failed with Couldn't save to memory. So did everything else that has to turn text into a vector: semantic retrieval over past conversations, automatic fact extraction, and the memory-aware pipeline nodes. If you tried it once, saw the error and moved on, that was this.
Only release builds were affected. The optimiser that runs on a release build — and only there — makes a class abstract when it can see nothing creating an instance of it. The library that parses the on-device embedding model's configuration never creates instances in a way the optimiser can see; it allocates them directly. So the ability to instantiate was removed from exactly the classes that get instantiated, and the embedder failed on its first call.
Nothing was lost or corrupted, and nothing needs to be reset. Saving simply refused to happen. It happens now.
Why it took this long to find
Four ordinary decisions lined up badly. Development and testing happen in debug builds, where that optimiser does not run. The failure is an ordinary exception that the app catches and shows as a small message, so it never became a crash report. A release build sends nothing to the system log, so reproducing it on a phone still produced an empty log. And the automated checks run on the JVM — they never execute the optimised app.
It was found by building a release-optimised copy that logs, installed alongside the normal app.
What stops it coming back
The build now inspects the packaged app itself and fails if a class that gets instantiated indirectly has been made abstract or removed. The previous check looked at whether such classes kept their names — which they had, which is why it stayed green while the app was broken. Both previously published versions fail the new check; that was confirmed against their APKs before it was trusted.
Upgrading
Same signing key as 0.7.0 through 0.7.2, so this updates in place. Coming from 0.6.0 or earlier still needs an uninstall first.
Which file
knotwork-0.7.3-full-release.apk— the normal build, for sideloading.knotwork-0.7.3-foss-release.apk— no Google or Firebase dependency anywhere in the graph, and no crash reporting.knotwork-0.7.3-full-release.aab— store upload format; not installable directly.
Checksums are in SHA256SUMS.txt. Requires Android 16 (API 36) and roughly 2 GB of free RAM for the model.
Full detail: the 0.7.3 section of the changelog.
v0.7.2
Nothing about the app's behaviour changes in this release. What changes is the contents of the file you install, which matters if you are the kind of person who unpacks it — and the FOSS build exists for exactly that person.
The FOSS build no longer declares any Google components
MediaPipe, which powers the on-device embedding path, brings Google's data-transport library along for its own logging. Three of that library's components — an alarm receiver, a job service and a backend-discovery service — were declared in the manifest of the build whose whole claim is that it carries no Google dependency.
Nothing could ever be sent through them: the transport implementation is stripped from the release build, and no collection endpoint reaches the app. That made them worse than useless rather than harmless — a manifest advertising a collector is the first thing someone auditing the FOSS build will find, and the honest answer to "what is this doing here?" was "nothing, and it should not be here."
They are gone. Verified on the published artefact: zero com.google.* components in the manifest, down from three.
The dependency itself stays. Excluding it leaves MediaPipe's own code referencing classes that are no longer in the APK, on the path that produced a release-only crash in the on-device memory feature once before. Removing three manifest entries reaches the same end state without putting that path at risk.
The APK no longer carries Google's encrypted dependency blob
The Android build tools stamp a description of the dependency graph into every artefact, in a form only Google can read. It is now omitted from the APK — the file you sideload and can inspect — and kept only in the bundle uploaded to Play, where it powers warnings about known-vulnerable dependencies.
Upgrading
Same signing key as 0.7.0 and 0.7.1, so this updates in place. Coming from 0.6.0 or earlier still needs an uninstall first — those builds were debug-signed.
Which file
knotwork-0.7.2-full-release.apk— the normal build, for sideloading.knotwork-0.7.2-foss-release.apk— no Google or Firebase dependency anywhere in the graph, no crash reporting, and now no Google components declared either.knotwork-0.7.2-full-release.aab— store upload format; not installable directly.
Checksums are in SHA256SUMS.txt. Requires Android 16 (API 36) and roughly 2 GB of free RAM for the model.
Full detail: the 0.7.2 section of the changelog.
v0.7.1
A privacy-focused point release: one thing the app was doing that its own settings screen denied, and one thing it could not do at all.
Turning on crash reports no longer turns on analytics
The consent toggle is described everywhere — in the setting itself, in the README, in the security policy — as stack traces only. It also switched on Firebase Analytics collection, quietly adding automatic events to what an opted-in install sent. The app has never logged an analytics event of its own, so that collection bought nothing and contradicted the toggle's own description.
Consent now enables Crashlytics and only Crashlytics, and the Analytics SDK is not shipped at all. The measured effect: the full build declares 13 permissions instead of 17 — AD_ID, both ACCESS_ADSERVICES_* and BIND_GET_INSTALL_REFERRER_SERVICE are gone. What a crash report can contain is unchanged.
If you had opted in on an earlier build, updating stops the collection you never asked for. There is nothing for you to do.
Report a response you think is wrong
Long-press a message the agent produced and pick Report response: choose a category, add a note, then either copy the report or open a prefilled issue. Nothing is transmitted on its own — there is no reporting server behind this app, and adding one would contradict everything else it claims. The dialog says so, and warns that the tracker is public before you submit anything.
A standalone privacy policy
PRIVACY.md now documents in one place what stays on the device, every path that can send data off it, what never leaves at all, and why each permission is requested. The About screen links to it, so the app, the README and any store listing answer with one document instead of three.
Also in this release
- Store listing texts, screenshots and graphics moved into the repository under
fastlane/metadata/android/, guarded by a test that enforces what the stores actually reject. - Two builds of the same commit now carry the same build date — groundwork for a release you can reproduce from source and check against the published artefact.
Upgrading
Same signing key as 0.7.0, so this updates in place. Coming from 0.6.0 or earlier still needs an uninstall first — those builds were debug-signed.
Which file
knotwork-0.7.1-full-release.apk— the normal build, for sideloading.knotwork-0.7.1-foss-release.apk— no Google or Firebase dependency anywhere in the graph, and no crash reporting at all.knotwork-0.7.1-full-release.aab— store upload format; not installable directly.
Checksums are in SHA256SUMS.txt. Requires Android 16 (API 36) and roughly 2 GB of free RAM for the model.
Full detail: the 0.7.1 section of the changelog.
v0.7.0
An on-device AI agent for Android, where you build the agent's behaviour out of
explicit steps you can inspect, and every dangerous action stops to ask you.
This release is mostly about the two paths that reach outside the phone —
connecting your own MCP server, and delegating a step to a cloud provider. Both
had been built but almost never run. They were run deliberately this time,
against real servers and real providers, and both were broken.
Before you update
The signing identity changed. Builds up to and including 0.6.0 were signed
with the Android debug keystore; this is the first release signed with a real
release key. Android refuses to update an install in place when the signer
changes, so upgrading means uninstalling the old build first — which deletes its
data. Export anything you want to keep before you do. One-time only:
releases from here on update normally.
What was broken outside the phone
Six independent defects, none of which any unit test could see:
- A third-party MCP server was unusable. The session was lost between the
health indicator and the executor; every tool parameter was declared to the
model as a string; and tool calls carried an accidental 10-second limit
inherited from an HTTP client default. Any one of them was enough on its own. - A cloud answer cut off in transit was shown as if it were finished. A
dropped stream ends normally on OpenAI-compatible clients — the only
difference is a missing completion signal, which was being discarded. A
configuration error was fed into the token stream, so a failed step read as a
success. And there was no deadline at all: a stalled provider held a step for
15 minutes (measured).
Fixed, with the limits now written down honestly in the
user guide
— including where the truncation protection does not apply yet, and why.
Two more found on the way: one hung tool call froze every chat in the app,
and a finished tool could run twice if the process died inside a 500 ms window.
Also in this release
- Local servers over plain HTTP actually work now. Approving your own
Ollama or MCP address on your network is a decision you make, not a list of
addresses baked into the APK. - Archive chats instead of deleting them — swipe, undo, restore, read-only
history. - A weekly view of your own usage, on-device: active days, current run,
returns after a break. Nothing leaves the phone; a build-time guard forbids it. - Model downloads survive leaving the app and resume where they stopped.
- Setup picks the fastest inference backend your device can actually run,
and quietly falls back when it cannot. - See what your automations are doing — an evaluation journal and health
badges say why a trigger did or did not fire. - Long-term memory recalls better: age no longer expires a relevant note,
near-duplicates are found by meaning, and a summary is verified before the
facts it replaces are deleted. - Steps inside a pipeline work in English; only what you read is translated.
Working in another language used to break tool calls and routing silently. - A pipeline import now names what it could not read, field by field.
Which file do I want
knotwork-0.7.0-full-release.apk— the normal build.knotwork-0.7.0-foss-release.apk— no Firebase, no crash reporting, for the
F-Droid-minded. Same behaviour otherwise..aabis for store upload, not for installing.
Verifying what you downloaded
SHA256SUMS.txt covers all three artefacts. The signing certificate is
SHA-256: E5:0C:8A:A4:7C:38:C8:08:E4:49:C8:7D:BC:D4:AB:9D:0D:81:0B:CD:8C:A9:D3:3F:D0:CE:83:D4:92:C8:16:51
Check it with apksigner verify --print-certs. Every release from here shares
this signer.
Pre-release
Version 0.7.0 is a pre-release: no stability guarantees for the pipeline JSON
schema, exported formats or settings layout, and shared pipeline files are not
yet a compatibility contract. See the Pre-release notice in the
README.
Full changelog:
CHANGELOG.md
— every change in this release, in full.