A week ago we published the thresholds behind automatic task matching — a score of 0.45, a margin of 0.15, sixty seconds of agreement. It felt like the honest thing to do. Then we measured what those numbers did on real workspaces, and it turned out that publishing them was honest about the wrong thing: a threshold we picked once, in our office, cannot be right for your task list.
Since then the matcher has been rebuilt around a single question — how do you know that? — and the fixed numbers are mostly gone. The bar a booking has to clear is now worked out from your own projects, every few minutes, on your own machine. This post is the measurement: what we count, what moved, and the one rule that survived every rewrite.
What “accurate” has to mean before you can measure it
Accuracy is a useless word here until you say which mistake you are counting. An automatic timesheet has two, and they cost wildly different amounts. It can miss work it should have recognised, which you notice immediately, because the row is empty. Or it can file time against a task that had nothing to do with it — which looks exactly like a correct row, and which you will not notice at all.
A wrong booking is more expensive than a missing one, because you cannot see it.
So the number we report is the second kind. The test feeds the matcher work that belongs to a project the workspace does not have, and counts how often it books anyway. Every answer is wrong by construction, so there is no judgement call in the scoring.
A second run does the opposite, and matters just as much: every one of those 481 titles is fed to a workspace that does contain it. There, silence is the failure. A matcher can reach a flawless false-positive rate by never speaking at all, so the two runs are read together or not at all. On today’s build that second run recognises 453 of the 481, is silent on 28, and names the wrong project exactly zero times — and that zero is a hard assertion in the test suite, not an aspiration.
The number, and where it went
Two thirds of the wrong bookings are gone, and neither step cost recognition of real work. The full breakdown of that last run is worth seeing whole, because the middle slice is the interesting one — it is where a booking goes when the app decides it is not sure enough to file an hour but is sure enough to ask.
Here is what each of the three changes actually was.
1. Refuse to book a window you cannot account for
The old gate asked whether a task scored highly enough. It never asked the reverse question: does this candidate explain the window? A page with nine words on it, of which a task matched two, could clear every threshold on those two words while the other seven — the ones actually saying what the page was — went unexamined.
Booking now needs two ratios, not one. At least half the content words on screen have to be words this candidate recognised, and at least 30% of the task’s own vocabulary has to appear. Fail either and the booking is refused. Crucially it is refused, not discarded: the candidate drops to the tier below and arrives as a one-click chip. Of the wrong bookings this removed, most went silent entirely and a handful came back as questions.
2. Let the workspace set its own bar
This is the change that makes the earlier post out of date. A threshold of 0.45 is a statement about how confusable your projects are — and we have no way of knowing that. Two agencies, one running twenty unrelated client projects and one running four near-identical rebuilds, need different numbers, and the second one needs a number no amount of care in our office would produce.
So the desktop app derives it. Every few minutes it re-scores a deterministic sample of your own task titles against your own projects and asks two questions: what does a right answer look like here, and what is the best wrong answer this workspace can produce? The booking bar is set above the second, with a widening allowance when there are few references to learn from.
That last row is the part we are most attached to. If the tenth percentile of a workspace’s right answers sits below the ninetieth percentile of its best wrong ones, then words simply cannot tell that workspace’s projects apart — and the app says so and stops booking, rather than performing the same guess with a confident face. The timer keeps running. Everything falls to a one-click chip, and the reason is written to the session record.
3. Weigh a shared word instead of deleting it
An earlier fix had struck any word appearing in two projects from the corpus outright, on the reasoning that a shared word distinguishes nothing. It was too blunt in a way that took a while to spot: a workspace with projects called Website Design and Android App would strike the company’s own name, which is correct, and also strike design — so the project whose name contains the word could not use it.
Words are now scored by how far past chance they point at one project, on a scale measured against how many projects you have. With two projects a word split evenly between them is exactly a coin toss, and used to look half-informative. Recognition of real work went up as a result, not down.
The rule that survived every rewrite
The original matcher read one thing: the window title. It now reads more — the browser’s domain and the first section of the path, the application name, whatever domains and keywords you have declared on a project. That sounds like a straightforward expansion of evidence, and it is the most dangerous change in the whole arc, because those signals identify a place and not a piece of work. Being on your client’s domain says which project you are in. It says nothing whatsoever about which task.
Location can produce a question. Only the words in the window can produce a booking.
The reason this is a hard rule and not a preference is that we broke it, twice, and both times it cost real hours. A project named after the product meant the product’s name appeared in every tab title in the workspace, where it quietly served as the second “independent” word that a confident booking requires. And an association learned from someone’s clicks — two confirmations on github.com — started booking personal repository browsing. Learned signals no longer book anything. They rank a question you still have to answer.
One word is not proof
The clearest evidence for all of this came from measurement rather than reasoning. Over nineteen hours of real use, the timer raised 379 questions. Of those, 264 came from a single ordinary word: monitor on a status-monitoring site, console on a scheduling service, model on GitHub, links in a search console. All of them were offered the same unrelated project.
The logic that produced them was not obviously wrong. A word appearing in exactly one of your tasks is rare, and rare looks like evidence — it is what makes ticket numbers work. But rare inside your workspace is not the same as meaningful out in the world, and naming a project now takes two distinct words. The cases that were already working had two all along; the 264 did not.
When there are no words at all
Most windows share no word with any task. A page can be plainly about your Android work and say nothing your task list has ever heard of, and every mechanism above will — correctly — stay silent. The last release in this arc added a channel for exactly that case.
The desktop app now carries a small open-source language model, MIT-licensed and bundled inside the installer, that turns text into a vector. Each of your projects gets one, built from its task titles; the page on screen gets one; the app compares them. When a page is near one project and clearly farther from the rest, that project is offered. It is roughly 17 MB of tables and a dot product — no server, no GPU, no request leaving the machine.
What makes it usable is the discipline around it, all of which was fixed before a line of it shipped. It never books. It never overrides a project the words already named. It cannot speak more than once an hour about any one website or application, because it fires precisely where nothing else could, so there is nothing available to check it — the rate limit is the check. Across all 190 pairings of the built-in project plans, 99.9% of the projects it named this way were the right one, with a wrong chip on 0.4% of pages about work the workspace does not contain.
A note on language, since we are strict about this elsewhere: the token matcher is not AI. It is a deterministic scoring function, and it behaves identically whether your tracking mode is Automatic or Rule-based. The resemblance channel is a model, and runs in Automatic mode only — which is what the rule-based mode is for.
What it still gets wrong
- 5.6% is not zero, and the remaining cases are not one threshold away. They are windows describing work that genuinely resembles work you have, which no fence can separate without also refusing correct answers. The next lever is a bigger vocabulary to explain windows with, not a tighter bar.
- A booking still consults no location. A page inside your client’s console can book a task from another project on one strong word, because the tier that books deliberately never learned to read the address bar. It is a known gap with a failing test sitting on it.
- The first minute of any window is silent. Booking waits sixty seconds of sustained agreement; a question waits ten. That is deliberate and it does read as slowness.
- Declared signals are the cheapest fix and nothing asks you for them. Telling a project which domains and applications belong to it beats every inference in this post, and it is a field on the project that most people never find. That is a product failure rather than a matcher one, and it is the one on this list we find hardest to defend.
The thing we would keep, if we had to keep one lesson from the week: a threshold with no provenance is a guess with a decimal point on it. Ours had provenance now — it is derived, it is written down, and when the workspace cannot support one, the app says so instead of pretending.