Twenty-three releases in fifteen days.
Ferrow is pre-1.0 and versioned in public. Every entry below is a real tag, on the day it was cut, and every fix names the thing that was broken.
0.1.22 · 24 Aug 2026
A threefold overcharge on every current-model request, a Windows download that could never start, and secrets held by a permission Windows ignores.
-
Current models were priced as their predecessors — three times over
The price table matched models by family pattern, and the pattern written for the previous generation of Opus caught the current one too. So every Opus request was costed at the older generation’s rate — three times the real one, in your disfavour, with no error and no line in any log to notice. Sonnet and Haiku had the same fault. The current families now carry their own verified rates, and a row must either declare itself a guess or name the date its price was checked; a table that could quietly keep an old number is what made this possible.
-
The Windows app could never start the engine it shipped with
The desktop download carried its own copy of Ferrow and then looked for it at a path that does not exist on Windows, so the app opened and never came up. The screen that was supposed to explain the failure could not navigate either, which is why it looked like nothing rather than an error. Both halves are fixed: the app finds the engine it was packaged with, and when a launch does fail it says so on a screen that loads.
-
A skill’s command could run nothing on Windows and report success
Every quote in a shell command a skill ran arrived at Windows escaped, so anything quoted — a one-line script, a path with a space — executed as an empty instruction and exited zero. A skill that did nothing at all was indistinguishable from one that worked. Commands are now handed to the platform in the form that platform actually parses.
-
Your API keys were held by a permission Windows does not enforce
Secrets on disk were protected with a POSIX file mode. Windows accepts that call, returns success and ignores it, so every key Ferrow stored on Windows was readable by any account on the machine while the product reported it locked down. Ferrow now sets and checks the actual Windows access list, and an inherited permission is not mistaken for a deliberate one.
-
Every “here is how to fix it” line was a command Windows cannot run
When Ferrow found a file it could not write or a secret left exposed, it printed a repair command — and that command was always POSIX. On Windows the closest equivalent resolves, exits zero and repairs nothing, so following the instruction left you exactly where you started while both you and Ferrow believed it had worked. Repair lines are now written in the host’s own shell, and the paths in them stop mixing two separators in one sentence.
-
One place decides what a plan costs
The price list existed in five copies — the site, the signup wizard, the app, the CLI’s help text and the billing code — and they had already drifted apart, so the page and the wizard disagreed about what you could buy. There is now a single catalogue the server publishes and every surface reads, prices and wording both, with a guard that fails the build if a surface starts carrying its own copy again. Alongside it: the 2026 model, custom top-ups from ten dollars, and a scheduled price change that happens by date rather than by somebody remembering.
-
A conversation survives the tab closing
Threads are records now, not screen state. Close the tab, reopen it a day later and the conversation is there, titled, with its history intact.
-
A modern tool server is no longer pinned to the old protocol for the session
Ferrow briefly probes a connected tool server to learn which revision of the protocol it speaks. A server that stayed silent through the probe — a slow start, a busy machine, one millisecond — was recorded as having answered that it was legacy, and stayed pinned there for the rest of the session with no way back and nothing said. Silence is now read as silence, and the question gets asked again.
-
ferrow logfound no history for a note it had just writtenThe change log recorded whatever path you happened to type rather than the note’s real location, so asking for the history of a note you had just edited returned nothing. Entries are recorded against the note itself, and the old ones still read.
-
Teams can bound one person’s mistake without bounding the team
Per-seat spend caps, an append-only audit log built from records the team already has rather than a second copy of anyone’s identity, and admin contracts that can only ever narrow what a seat may do — never widen it.
0.1.21 · 14 Aug 2026
A checkout a crawler could open, a locked vault we called empty, and screens that spoke for a gateway that had said nothing.
-
A crawler looking at the buy button no longer starts a checkout
Every link to a plan went through a handler that minted a live Stripe session on the way past — and a search engine, a link preview or a browser prefetching what it thinks you are about to click sends a request too. So sessions were being created for readers who never clicked anything. A look is a look now: only a real click creates a session, and the buy links tell crawlers not to follow them at all.
-
The gateway address in the shipped build is the one that answers
The default host baked into the build was not the host serving the API, so a machine that had never been configured by hand asked a place that had nothing to say. Worse, the 404 that came back was read as a rejected key — the product telling a paying customer their key had been revoked when it had only ever knocked on the wrong door. The default is
api.ferrow.ai, and a 404 there is reported as the wrong address, never as a revoked key. -
Billing screens stop speaking for a gateway that said nothing
An account whose status the gateway did not report was drawn as active, and an account whose edition it did not report was described as being on your own API keys — the opposite of the truth for a Managed customer, and it swallowed the spend-cap figures that had actually arrived. Absent is its own answer now, on every surface. Alongside that: a lifetime buyer is no longer offered a subscription cancellation they never had, the four statuses that mean the account is already switched off render as exactly that on the desktop panel instead of a healthy plan, a trial states the day it ends rather than implying one, and the browser panel — which kept its own copy of the card row — now says the same sentence to a customer in dunning that the desktop does.
-
A failing card has the same repair everywhere
ferrow billing cardis what every dunning email, revoked-key panel and recovery screen points at, and when the call could not leave the machine it printedfetch failedand stopped. It says what did not happen, why, that the card and plan are untouched, the retry, and the human path. The desktop billing panel now carries the portal link beside the state that needs it, so the fix is on the screen that reports the problem. -
A vault Ferrow cannot read is not an empty one
A folder Ferrow could not open was reported as a count of zero — by search, by
doctor, by the hub, by the chat reply and by the tools a model calls. A person might go and look; a model will not. Every one of those names the path and the permission instead, and a search that could only read part of a vault says the answer is partial. The two importers refuse outright rather than treat an unreadable folder as an absence of collisions and overwrite notes at their wanted paths. And a folder that will not take a write is your machine saying no: read-only mount, wrong owner, full disk and quota each get their own true sentence with the remedy that actually applies, naming the folder — not an internal temp file, and never a claim that Ferrow has a bug. -
A damaged change log is named by line, and undo will not guess
ferrow logcounts the lines it could not read and says where they are, anddoctorstops certifying a damaged undo history as healthy. A short change id is refused against a history that was only partly read — that is how an ambiguous prefix reverts the wrong change — while a full id still works, because a corrupt line must not become the reason you cannot fix your own notes. If something does crash, the report on screen names the crash log it just wrote. And a vault whose MCP registry was written by a NEWER Ferrow is left alone rather than silently re-stamped by an older one. -
The command line answers a script honestly
haltandresumereturn the exit code that matches the state of the machine, so a script can branch on it, and turning the safety off from a script is now as explicit as turning it on.ferrow note --json "x"used to write a note called--json.mdand report success — a filermitself refuses to delete. An unrecognised flag is refused by name with nothing written.--global, which parses everywhere and is honoured by three commands, is refused on the ones that ignored it, andforget --globalnow forgets the fact you actually stored. -
The first five minutes, and the last
The quickstart’s second line described a key search the product does not do, on both front pages; the copy now matches what
detectactually looks for. The free button at the top of the funnel landed on a parameter the app read nowhere, so the one click that costs nothing produced no form and no acknowledgement — it opens the account form with the choice shown back to you. Anduninstallstopped telling five users in six to run annpmcommand their machine may not have: it detects how this copy was installed — app bundle, package, AppImage, npm — and prints the one instruction that removes it, or names all six channels when the evidence is not conclusive. -
The app host stops answering 200 for pages that do not exist
Every unknown path on
app.ferrow.aireturned the sign-in shell with a success status, and nothing on the host ever told a crawler not to index it — on the domain customers type their password into. There is a real 404 page now, and noindex is stated four ways so no single missing layer undoes it. The marketing site stays indexable. Bug reports from the desktop builds and the Android app arrive labelled as what they are, rather than as a stranger’s browser tab. -
The privacy page states in full what Google data we touch
For the YouTube integration: what is accessed, what it is used for, what is transferred, how it is protected, and how long it is kept — plus an affirmative Limited Use statement and an explicit clause that none of it trains a model, ours or anyone else’s. The retention wording says what the code does, which is an append-only local ledger with no timed purge, rather than a deletion policy we do not enforce.
0.1.20 · 14 Aug 2026
A plan we did not recognise, a stack thrown at the person who typed the command, and a README that oversold us.
-
A subscriber on their own key was told to subscribe
Whether your calls route through us and whether you are on a plan are two questions, and the product only ever asked the first one. So a paying Private subscriber — whose calls spend their own provider key, correctly, without touching our gateway — was told “this machine is not on a Ferrow plan yet” and invited to buy what they were already paying for. Entitlement is its own answer now, on either edition, and it counts a purchase only once the checkout actually completed and was not cancelled since — an abandoned checkout is not a subscription.
-
A billing record we cannot read gets one verdict, not three
A corrupt
billing.jsonused to mean something different depending on which command you asked.doctor,billingandunsubscribenow say the same thing about it, and none of them treats an unreadable record as an absent one. Alongside it:unpaid,incompleteandpausedeach get their own true sentence instead of sharing a vague one, and a cancel the gateway refused is never reported back as a cancellation. -
Rotating a key replaces the old one, and cannot cross the test/live line
Rotation used to be able to leave two keys on a machine, and to hand an activated machine a key from the other side of the test/live boundary. It is one operation now: the new key replaces the old one or nothing changes, and a key from the wrong side is refused by name rather than written.
-
A crash prints a sentence and a file, not forty lines of Node
An unexpected error used to dump the whole stack at whoever typed
ferrow note— noise to them, and useless to support, because a stack that scrolled off a terminal is a stack nobody can attach to an email. Ferrow writes the trace to a crash log first, then says one sentence naming that file and where to send it;FERROW_DEBUG=1puts the stack back on screen. The log is scrubbed of anything that looks like a key before it is written, and only the newest five are kept.ferrow doctor --bundleassembles the same evidence on purpose — environment header, full report, settings — through the same scrubber.doctor’s header now carries the three facts support opens with: Ferrow version, Node version, platform. -
Refusals that name the thing that did not run
A halted command used to answer with the governor’s internal call site. It names the command that did not run and the verb that lifts the halt.
--vaultpointed at a file answers in one sentence instead of six frames of stack.uninstall’s “the vault is yours” now prints the path, so a departing user can go and check it is still there. Andconnectsays where to get a key once, next to the prompt that wants it, instead of twice. -
The web app can fix a failing card, and stopped losing what you typed
Settings opens the Stripe portal that the dunning email has always pointed at, so a card that started failing can be replaced without leaving the app. Text you have typed in Settings survives the repaints the meter and key reads fire. Enter obeys the same gate the Send button does, so a second message cannot ride over one still in flight. And
ferrow uican report a bug from the foot of the window — which is where the support page had been sending people all along. -
A README that says what we actually are
The free tier is a row in the table rather than a footnote, the relay is described as the built thing it is, and “no server component” is gone — it was never true of a product with a hosted gateway. The signup click before a card number lands on
api.ferrow.ai, not a workers.dev deploy name, and the trialing example on the pricing page carries a placeholder date so it can never read as expired.
0.1.19 · 14 Aug 2026
A screen that froze, a card you could not fix, and a schedule that only ran while you watched.
-
The signed-out Settings screen stopped the window redrawing
Two rows on Settings read from a session that was not there yet, and the throw landed in nothing — so every later click re-entered the same failure and the app stopped painting, on the exact screen a new visitor is sent to in order to sign in. Both rows answer the signed-out case in words now, with the two ways in, and a guard under the router costs one screen instead of the application the next time a view throws.
-
The message box on the home screen refused the accounts it was offered to
It was enabled for anyone holding a session, which is every signed-in account — so a free account got a 402 and a subscriber on their own provider key got “this endpoint is for the Managed edition”, permanently. One decision now reads the tier and the edition, and the box, the button, the sentence above them and Enter all obey it. Each refusal names the action that is actually true for that reader.
-
Billing called our outage your cancellation, and a failing card had no repair
A gateway that could not be reached was reported as a plan that had ended, and
fetch failedwas printed at a customer as if it were a sentence. A dead provider key was reported as a missing one. And a card that had started failing had nowhere in the product to be replaced. Each of those is now its own message, and the card can be fixed from the terminal —ferrow billing cardopens the portal Stripe hosts for exactly that. Usage packs are a command as well as a website button —ferrow subscribe pack-25— and a top-up is stated as a top-up: it adds credit to the plan you already pay for, and nothing renews. -
Schedules were only ever going to run while something happened to be open
A schedule you set was a promise kept by whichever process was still alive. The hub is the timer now:
ferrow hub startis what makes a schedule real, and a schedule with no hub says so instead of waiting silently for a moment that never arrives. -
The doors a script needs, and an update row that asks
connectworks with no keyboard, through a namespaced environment variable rather than a bare one nobody offered us.providersanddoctorspeak--json, and the human output is byte-for-byte unchanged without the flag.doctornow tells you whether a newer Ferrow exists — only when you run it, because a background check is telemetry and /privacy says there is none. Anduninstallshows you what is on the machine before it removes any of it. -
A key file we cannot read is never overwritten
A keystore Ferrow could not decode used to be replaced. It is left exactly where it is now, and the doctor says what it found — the failure mode here is somebody else’s data, and the only safe move is not to write.
-
A promise retired rather than restated
The bug-report form in the app said we answer within a day. No queue reads that inbox on a timer — Ferrow is pre-1.0 and small, a reply takes as long as it takes a person to get to it, and the form says that now instead of a number nobody was keeping to.
0.1.18 · 13 Aug 2026
Your key went to our server, and cancelling asked you for ours.
-
The private Council sent your provider key to api.ferrow.ai
On any machine not on a Managed plan,
ferrow councilposted your provider key to our Worker and ran the five seats and the chair there — while the terminal said “your key runs the reasoning server-side, never stored” and /privacy said a provider key “is never sent to us”. Both cannot be true. The private Council now runs entirely on your machine, over the same model connectionferrow chatuses: not the question, not the context, not the key reaches us. The endpoint that accepted keys is deleted rather than deprecated — a request carrying one is refused before anything is read, so an old client is told to upgrade instead of being quietly served. Managed is untouched: a plan holder’s Council still runs on Ferrow’s own keys, which is what the plan is. What this cost was prompt secrecy; the personas ship in the package again, and a parity test holds the two copies byte-identical so a verdict on a plan and a verdict on your own key come from the same prompts. -
A keyless local model could not hold a Council at all
Ollama, LM Studio and a custom base URL have no key to spend and no address our server can reach, so the hosted path had nothing to do with them. That falls out of the fix above: the Council is local, so a local runtime holds one.
-
ferrow unsubscribeasked customers for a Stripe secret/refunds promises “cancel any time, in one command”. The command called Stripe directly, so it wanted an
sk_…key and printed a keychain recipe to a buyer who has never held one — and never should: a Stripe secret is the whole account, not one subscription. Cancelling now goes through the gateway on the machine’s own Ferrow token, and the subscription cancelled is the one that token names, never an id from the request. It still cancels at period end, so what you paid for keeps working; inside the 3-day trial nothing is charged at all, and the terminal says which of those two happened because only the server knows. A refusal says NOTHING WAS CHANGED on its first line and exits non-zero — a failed cancel reported as a cancellation is the one failure here that costs money.ferrow billinghad the same hole on its fallback and lost it too. -
connectverified a model and then forgot itconnect customlisted the endpoint’s models, tested one, and stored none — sorun,councilandworkflowdemanded--modelforever after, against a promise on /docs that the connection is enough. The model the connect actually exercised is now part of the connection. Nothing is ever invented: an endpoint that lists nothing stores nothing, and the CLI still asks. -
ferrow detectfound your runtime, then the front door said noneDetect printed LM Studio’s address and models and said “chat with one”; the front door then said “none connected yet” and sent you back to
ferrow detect. A runtime that is up needs no key and no file — it is a complete connection, and it counts now, by its real name and with its real models. A stored connection still outranks a detected one, and detection only speaks when nothing is stored, so a settled machine does not become an ambiguous choice because an Ollama was left running. -
Four sentences that named somebody else’s account, or nothing at all
The no-model error offered
--provider openai --model gpt-4o-minifour times to a reader who by definition had no OpenAI account; it now offersferrow connectandferrow detect, and no placeholder provider or model appears in it.ferrow chattold a connected machine there was “no model to send that to” when there was one, and now names it.ferrow providersprinted a dash in the key column for a keyless connection, which reads as “it did not take” — the column has three values now, and the dash still means what /docs says it means. Andferrow connect --helpansweredUnknown provider "--help"and exited 1, telling you your provider was wrong when your question was which providers there are; every subcommand answers--helpnow, from the same rows as the manual, and exits 0. /docs and QUICKSTART moved with the code, because a page showing a screen the program does not print is the thing those transcripts exist to prevent.
0.1.17 · 13 Aug 2026
The front door could not see the connection you had already made.
-
Bare
ferrowsaid “none connected yet” to a connected machineSeconds after
ferrow doctorreported “1 connected: custom”, the front door told you to start over and connect a model. It only knew how to count stored keys — and the setup we recommend most, a local runtime saved byconnect custom --base-url …, stores no key at all. Welcome and doctor now read the same list of connections, so they cannot disagree. The front door still never waits on the network to say it: it reads what is configured, offline and instantly, and leaves the probing todoctor. -
ferrow runignored the connection and named a provider you may not haveFollowing the docs — connect, then run — answered “No provider or model set. Pass them:
--provider openai --model gpt-4o-mini”, which is a command about somebody else’s account.run,councilandworkflownow fall back to the connection you made, with the modelconnectverified it against. If several are connected that is a real choice, and the question names the providers on this machine. With nothing connected the canonical example is unchanged, and explicit flags still win over everything. -
Three smaller sentences that were not true
doctoradded “(stored in your keychain)” to a connection that stores no secret anywhere — on the one command whose whole job is to be believed; it now says that only when there is a key.connect custom --base-url 127.0.0.1:1234/v1, the shape you copy off a local server’s own startup line, went to the wire and came back quoting a parser error about a URL you never typed — the missing scheme is caught before the request now, and answered with the line you meant. Ferrow does not guess betweenhttpandhttps: they are different promises about the same address. And a scriptedferrow haltwith no terminal was told to runhalt <reason>, which asks the same question it could not answer. -
Three claims on the site that pointed at nothing
/terms §10 deferred to “the EU and UK rights above” when those rights are set out on /refunds, not above — a governing-law clause citing a passage the reader cannot find. It names the right and links the page it is on. /privacy named the trading name twice and never the person a data-protection request has to be addressed to; it now says it once, in the same words /terms uses. And the Lifetime sub-line “less than ten months of the yearly price” only lands against the yearly rate, so a reader holding the monthly number got a different sum; the rate it is measured against is named. /docs step 7 also framed the no-model screen as the only outcome — with the fallback above, a connected reader needs no flags, and the prose says so before the transcript.
-
Two lanes publishing the same download could overwrite each other’s bytes
The hash beside every desktop build on /download is now taken from the bytes dl.ferrow.ai actually serves, read back in full after upload, and a difference is a hard failure rather than a quiet pass. A publish also takes a lock for the version first, so two machines can never notarize and upload rival copies of the same file. Nothing about the downloads changed; what changed is that the number printed beside them is one you can reproduce.
0.1.16 · 13 Aug 2026
Four screens that left you stranded, and a contract that named nobody.
-
connect customthrew away the endpoint you had just typedThe wizard asked for a base URL, tested it, said “Connected” and told you which chat command to run next — then saved the key and nothing else. The command it had just recommended died one line later on a missing base URL, and
ferrow modelsshowed acustom (error)row with no documented way out. The endpoint is now stored with the key, so a connection is a connection.connect custom --base-url <url>answers the one question a script could not answer, re-running the wizard offers the endpoint you already gave it, andconnect <provider> --forgetdrops key and endpoint together. A local runtime with no key at all now shows up inferrow models, which is exactly the case the escape hatch exists for. -
ferrow doctorhad never once seen a stored keyIt said “No provider key stored.” and “Nothing is broken.” on installs that had keys in the keychain and were printing an error row two commands earlier. The probe was asking a list of provider names whether they had a key, which a name can never answer, so every key read as no key.
doctorandmodelsnow read the same provider state and cannot disagree: an error row is a fault here too, in the same words, with the two ways to fix it named. A keyless local endpoint counts as connected; a genuinely fresh install is still just unset, not broken. -
ferrow haltdid not halt, and did not say what wouldThe kill switch, run with no argument, ended at “Left running. Nothing changed.” — which is the wrong sentence to read in the moment you reach for a kill switch, because it names no spelling that works. It now tells you the one that does. The signature is
halt <reason>: bareferrow haltasks rather than halts, and it says so. -
Making a second project made your first one disappear
ferrow project new workmoved you into the new vault, and your original~/FerrowVaultstopped existing as far as the CLI was concerned:project listshowed only the new one,project switch defaulterrored, and the only route home was deleting the project you had just made. There is now always ahomerow — listed, switchable, and refusing to be created over or deleted. Nothing migrates and nothing moves on disk; being onhomeis the state every existing install is already in. -
The signup wizard ran its own sentences together, and its cap panel repeated a claim we had already corrected
Step two read “Free, on this machine. No card.An email and a password…” — title welded to description, because the description was styled as a block and rendered inline. The doors have their type scale back. The pay step now says which recovery route actually applies to you: if you skipped making an account, it points at your Stripe receipt and support instead of a Settings page you never created. And the ceiling panel said “No cap set yet” when there has always been a $20 default, and repeated the “will not spend past it” wording the sales pages dropped this round; it names the default and says Ferrow stops before any call that would cross it. The panel’s spend-cap example is now spelled the way the help, the docs and the pricing page spell it.
-
The last places the spend-cap overclaim survived
The home page and the Managed card on /pricing still promised Ferrow would never charge past your cap, and /terms said it in different words again. The meter refuses a call whose estimate would cross the ceiling — it stops before, which is the stronger sentence and the checkable one. All three now say it. Nothing about your cap changed; only the claim about it did.
-
The terms name a governing law and a seller
The contract page admitted it had no governing-law clause. It now names California. The terms and the licence also name who the receipt comes from: Christopher Ruzylo, doing business as Ruzylo Holdings.
0.1.15 · 13 Aug 2026
Four sentences Ferrow could not stand behind, and a trace that named nothing.
-
“Never charges past your cap” was a promise the meter does not make
ferrow billingand the CLI help both said Ferrow never charges past the cap you set. What the meter actually does is refuse a call whose estimate would cross the cap — it stops before, which is a different sentence and the one you can check against the reservation. Both lines now say the thing that is true. Nothing about your cap changed; only the claim about it did, and the tests that used to pin the overclaim word for word now pin the accurate line and fail if the old one comes back. -
The rate card the CLI previews your cost from was the provider's price, not ours
Ferrow publishes one rate card, and the CLI caches it to show you what a call is about to cost before you make it. It carried the provider's per-million list price while your bill is computed from that plus Ferrow's fee — so every local preview came in under the real number. The card now publishes the charged rate, derived from the same constant the meter bills with, and each row says
basis: chargedso nothing can quietly drift back. You pay for what you use; the preview now says how much that is. -
If you bought Ferrow in a browser, there was no way to stop paying
The desktop window had a billing panel — plan, spending, and a button that ends the subscription. The web app imported none of it, so a customer who paid on a phone saw no plan, no spending, and no way out, while the trial letter told them to use a Settings control that did not exist on their screen. Settings › Account now draws the same panel from the same account data the desktop uses, cancel included, and says the outcome in the same words. The receipt letter now also carries the renewal interval, the price, and both ways to cancel — and tells a one-time purchase the honest opposite.
-
You paid before you were ever asked to agree to anything
Every buy button went straight to Stripe, where the only thing anyone clicked was “Pay”. Terms nobody accepted bind nobody — including the parts written to protect you. Checkout now collects a required agreement to the terms and records it against the purchase, and the in-app signup’s pay step grows the matching tick with the terms one click away; the payment link does not appear until a plan and the tick are both true, and changing the plan drops the tick.
-
ferrow workflow runprinted a trace of bare event namesEvery run printed
· step_start,· step_done, and nothing else — no step name, which is the one thing a per-step line exists to tell you. The reader was looking for a field the workflow kernel has never emitted, so the name was always dropped silently. The trace now reads· step_start draft, and a test replays the kernel’s real events through it so the two cannot part company again.
0.1.14 · 13 Aug 2026
Everything a beginner was told to do next, that did not work.
-
The app opened a second, empty vault beside the one you had already filled
Run
ferrow vault init, write notes, open the desktop app — and meet a different vault with nothing in it. The terminal made~/FerrowVault; the app made~/Ferrow, said nothing about it, and your writing sat on disk and invisible, which is the worst thing a tool you keep your thinking in can do. The app now looks at what is already there before it creates anything: an existing vault wins, and if you have both, the one the terminal uses wins and the other is named on screen with the command that switches to it. A machine that has been writing into~/Ferrowsince 0.1.13 keeps it. That name was wrong twice over —~/Ferrowis also the folder that holds your projects, so every project had been sitting inside the app's vault as ordinary notes. -
Four recovery screens that sent you somewhere you could not go
Each of these is Ferrow's own here is what to do instead line producing the next dead end. The no-provider screen offered
export FERROW_PROVIDER=openai, which is a bash line, to a reader our own docs had put in PowerShell three screens earlier; both forms print now, each labelled with whose shell it is.ferrow detect, having found no local model, offered to point Ferrow at a base URL — the expert's escape hatch, handed to the one person who by definition has no endpoint; the hosted route is named first now, with a real provider id.ferrow connect openaiwith the key left blank called the API anyway and came back with "the API key was rejected", about a key that was never typed and never sent; the empty answer no longer reaches the wire, and says so. Andferrow billingnamed the Private plan without ever saying what Private is — it now carries the same words checkout uses. No price changed. -
ferrow log revertrefused an id that was printed on the screen above itChange ids are twenty characters that all begin the same way, so you type the part that tells them apart — and got "There is no such change", about a change listed in the table you had just read it off. An unambiguous prefix resolves now, from the front of the id or from after the
chg_that carries no information, and a full id still wins outright. A prefix that matches more than one change lists the candidates and reverts nothing: guessing which one you meant is the most destructive thing this command could do.
0.1.13 · 13 Aug 2026
It runs on Windows, and a hook can no longer take the process down.
-
Windows was never actually a supported machine, and now it is
ferrow --versionprinted nothing on Windows, because the version is read from the package beside the entry file and the entry's location was being handed around as afile:URL rather than a path — on a Mac the two happen to look alike, on Windows they do not. The same confusion meant the download tarball could be neither built nor opened there. And every skill that runs a shell command failed silently: no output, no error, no refusal. All three are fixed, and the test suite now runs on a Windows host rather than being graded only where the bugs cannot appear. -
Forty places where a progress callback could kill the run
Ferrow lets you pass callbacks that watch a long job — a step finished, a page loaded, a message arrived. Those calls were wrapped so that a callback that throws cannot end the job, but the wrapper only caught the immediate throw: an
asynccallback that failed a moment later escaped it, and an unhandled rejection ends a Node process. Forty call sites now go through one notifier that holds both cases, and the check that certifies them reads the shape of the code rather than a comment someone remembered to write — it was previously not even looking at the browser client that ships inside the tarball. -
Three promises this site could not keep on your operating system
/privacy and /welcome told every visitor their key was stored at
mode 0600. Windows has no such mode, so that sentence was false for everyone who bought the.exe. Both pages now say what is actually true per system, including the condition that stops it being a half-promise: point Ferrow at a folder outside your user folder and other accounts on that PC can read it. /docs likewise showed a Unix path the Windows CLI never prints. And the copy button on every command block had lost its clearance, so the tail of the longest command sat underneath it.
0.1.12 · 12 Aug 2026
The build you can download stops needing an excuse.
-
Both Mac builds are notarized, and there is one for an Intel Mac
Each
.dmgnow gets its own notarization ticket from Apple and has it stapled into the file before its sha256 is taken, so it opens without the unidentified-developer refusal and it does so with no network connection. The Intel build is new: the Apple-silicon one was the only Mac download for four releases, and an Intel Mac had nothing to click. The download page lists both, with the line that tells you which Mac you have. Windows is still unsigned and still says so on that page. -
Your subscription can be ended from the app you bought it in
Cancelling was a terminal command, on the machine holding the key. The desktop account panel now shows the plan and what has been spent, cancels there, and can reveal the product key so a second machine can be switched on — and it asks Ferrow rather than the keychain, so a machine that never held the key can still cancel. A cancellation already pressed hides the button instead of offering it twice.
ferrow unsubscribeis unchanged and still does the same thing. -
The tarball on the download page is the tree the page was built from
The
.tgzserved beside the one-liner had fallen behind the commit this site is built from, which the drift check had been reporting red for five runs. It is repacked at head, the sha256 printed on the download page is the stamp of that file, and every surface that states a version — CLI, desktop, mobile, Settings, theferrow uibanner, the package — says 0.1.12.
0.1.9–0.1.11 · 12 Aug 2026
Three in an evening, and only one of them reached you.
-
The tarball had been carrying a build cache that was never ours to ship
0.1.10. The package manifest swept a directory the site's deploy tool writes into the published tarball on any machine that had deployed this site — 192 files where a clean checkout produces 190, so the local check passed and only the build refused. The packed artifact is 190 files again, the pack step now fails outright rather than quietly including it, and the sha256 on /download is the stamp of the clean one.
-
One number, seven places
0.1.9 put the same version on all seven surfaces that state one in the source tree — the CLI, the desktop shell, the iOS and Android builds, the Settings screen, the
ferrow uibanner and the package. 0.1.11 made that a single command instead of seven hand edits, which is the only reason it will still be true next week. The downloadable desktop and mobile builds are re-cut per platform and can trail the CLI by a release — the version on the download page is always the truth about what you can install today.
0.1.8 · 12 Aug 2026
Notes you can edit in the window, and a browser that cleans up after itself.
-
The desktop window writes, and cannot lose a version doing it
The shell the desktop, iOS and Android apps all load could open a note and not change one — you had to leave the app to fix a word. It edits and saves now, through the same path the CLI writes on, so every save is in the change log and
ferrow log reverttakes it back. If the file moved underneath your editor the save is refused rather than allowed to overwrite, and you are shown both versions and asked which one wins. -
The agent's browser stops leaving things running
ferrow browserruns one command at a time, times out on a step that hangs instead of waiting forever, says so plainly when the browser has crashed rather than reporting an empty page, and leaves nothing behind when it is done. -
Four errors that were answering the wrong question
A misspelt skill name now reports that there is no such skill, rather than complaining that no model is connected. Piping any command into something that closes early —
ferrow loginto a pager you quit — ends cleanly instead of printing a crash. The two screens that answer “where are my notes” print the path instead of swallowing it. And a note brought in byferrow importlands in the project that is actually open.
0.1.7 · 12 Aug 2026
The desktop builds get a home with room for them.
-
Installers you can actually download, with the hash beside each
A build carries the engine now and runs from 21MB to 114MB, which is past what this site's host will serve at all — so the macOS, Windows and Linux installers moved to
dl.ferrow.ai, and the Linux AppImage is listed for the first time. Every row on the download page was fetched and hashed before it was allowed on the page, and the signing state is written next to the file rather than left for the operating system to tell you. -
Every page is the same product
The light, the furrow and the reveals used to exist only on the home page, so anyone who arrived on /terms from a receipt met a different site from the one that sold to them. They are on all eleven pages now. The focus ring was re-cut in the same pass: it failed its contrast floor in Daylight and passes it now.
-
The mail a subscription is supposed to send
A receipt with your key, a reminder before a trial ends, and a real message when a card fails — each of them sends now. Before this release the subscription worked and the person who bought it heard nothing.
-
This page, and a way to count the funnel that is nobody else's business
The changelog you are reading, plus
ferrow ops funnel: first-party counters, on our own server, so we can tell whether an install finished without putting an analytics script on a site that promises there is none.
0.1.6 · 12 Aug 2026
The registry name, and the mail that had never sent.
-
Install by name
npm install -g @ferrow/ferrowworks. The bare name is permanently refused by the registry, so the scope is not temporary and every install line on every surface now carries it. -
Transactional email is live
Password reset mail is verified on the ferrow.ai domain and proven delivered. Before this the reset flow existed and the message did not arrive.
-
Seven papercuts on the first-run path
A free arrival no longer claims you bought something. One name for the paid model tier instead of two. No payment framing before the free door.
ferrow hub statusstops sending you round its own circle, andferrow uiprints an address you can actually click. -
Privacy corrections from a blind walk
Three claims on /privacy were wrong and are fixed: the CLI's account and billing calls are now named as a real network surface, the no-network claim is scoped to your notes, and the password iteration count is stated as the number the platform actually enforces.
0.1.5 · 12 Aug 2026
A free account you can create and then use.
-
Free signup to an activated machine
The path from making a free account on the website to a terminal that knows about it is now walkable end to end, and
ferrow activatetakes a free account key the same way it takes a paid one. -
Password reset shipped
Nobody who forgets a password loses software they paid for. Reset, verify and resend exist on the web client and in the desktop shell, and the mail seam fails closed rather than pretending it sent.
-
The download hashes were crossed
The macOS row published the tarball's sha256 and the tarball row published the disk image's. A customer checking either one would have read their download as tampered with. Both are correct, and a test now derives every row from the file's own bytes.
0.1.4 · 11 Aug 2026
Free is a tier, not a locked product.
-
Local stays free
Vault, notes, search, log, skills, agents, local models and your own keys run with no account and no plan. Every server-side door refuses a free account with one honest sentence naming what it would take to open it.
-
Accounts had never worked in production
The platform the account service runs on refuses password hashing above a certain iteration count, and every credential route had been answering with a server error since the day it deployed. Found by walking the product as a stranger, not by a test.
0.1.3 · 11 Aug 2026
The download is the tree, and the page says so.
-
The tarball is packed from the ref
It used to be packed from whatever was on the packer's disk. Now it comes off the tagged tree, the sha256 on /download is derived from the artifact's own bytes, and a deploy that disagrees with the committed ref turns a gate red.
-
The site cannot teach a command the download will not run
A gate reads every command printed on this site, packs the tarball a customer downloads, and asks that binary whether the verb exists. It found one, and this release is where that stopped being possible.
-
A failed command answers with a diagnosis
Not with its own usage screen.
ferrow haltalso learned to be asked rather than only obeyed:ferrow halt --statusreports and never halts. -
The version declares itself everywhere
The CLI, the desktop shell, the iOS and Android builds, the Settings screen and the
ferrow uibanner all state the same number, so a bug report can name a build.
Before that
0.1.0 through 0.1.2, 10 and 11 Aug 2026.
The first public builds: the CLI, the local browser UI, the relay and the paired browser client, Stripe checkout, and the four release candidates that came before them. They are not itemised here because nobody outside the build installed one, and a changelog that pads itself with its own rehearsals is not worth reading.
Every current artifact, with a sha256 for each, and the five-minute walkthrough if this is your first one.