All posts
How it worksTask trackingAutomatic timesheetsOn-device matchingProduct engineering

How tracked time finds the right task

Automatic timesheets usually work by guessing, and a wrong booking costs more than a missing one. Here is the matcher we built instead, with its thresholds.

TO
The TimerOS Team
Vezoft
8 min read

Anyone who has kept a timesheet knows Friday afternoon. You look back at a week you definitely worked and try to remember which part was the migration and which was the bug that ate Tuesday. The hours were real. Nobody wrote down which task they belonged to, because that meant stopping work to press a button.

TimerOS has recorded hours automatically since launch. Until this month it could not say what they were for. Since v1.3, the desktop app matches those hours to your open tasks as you work, entirely on your own computer. Here is how it decides, and when it deliberately decides nothing.

It is in beta, and it runs on Windows
Task matching is marked Beta in the desktop app while it settles. It is on by default and you can switch it off in Settings. You can review, reassign or unassign every automatic booking. It runs only in the Windows desktop app (the web dashboard has no matcher). Matched hours count as tracked time on the task, so since v1.15.0 they also appear on time-and-materials invoices.

Why guessing is the real risk

The obvious approach is to take whatever is on screen, find the closest-sounding task and book the time. It looks great in a demo and does real damage, because a timesheet that is 80% right is worse than one that is 60% filled. The wrong 20% looks exactly like the correct rows. So you either check every row, which takes longer than filling in the timesheet yourself, or you bill a client for work done on a different job.

A wrong booking is more expensive than a missing one, because you cannot see it.
— This is the design constraint the whole matcher is built around.

So the matcher holds back. It needs solid evidence before it books anything, and when it does not have it, the time stays productive but unassigned. The app treats that as a normal result and does not nag you about it.

Updated 18 August 2026
This post describes v1.3. Four things have changed since. The matcher now also reads the browser’s address and the application name, but only to ask you a question, never to book an hour. The thresholds below are now fallbacks: the app calculates its own from your workspace and turns booking off entirely when your projects are too similar to tell apart by their wording. Since v1.9.0 an on-device model can also suggest a project, though it never books time to one. Since v1.15.0 a task’s hours come only from tracked time, and time-and-materials invoices bill them, so matched hours can now end up on an invoice. What changed, and what the measurements showed.

What it actually reads

In v1.3, just one thing: the title of the window you are looking at. It does not use the application name or the browser address. Those two only help decide whether you are productive or idle, and play no part in matching a task. The scoring code receives the address and deliberately ignores it.

The title is split into words and compared with the words in your own open tasks and subtasks. Words from a task’s title count in full; words from its description count at 40% and can only raise a score, never lower it. Rare words count for more than common ones, and about 130 generic words (fix, bug, update, task) are ignored completely. So “Fix login bug” and “Fix export bug” are told apart by the words that actually differ.

What a match has to pass

A candidate task has to clear all of these before anything is booked:

  • Two matching words, or one unique word. A single shared generic word is never enough. One word is enough only if it appears in exactly one task in your whole list, which is why ticket numbers work.
  • A score of at least 0.45. That is the share of the task’s title words found in the window title, with rare words weighted more heavily.
  • A winning margin of 0.15 over the runner-up. When two similar tasks score closer together than that, the matcher books nothing instead of guessing between them.
  • Sixty seconds of agreement. The same task has to keep winning repeated checks for a full minute before it gets its first booking. Alt-tabbing past something for fifteen seconds books nothing.
Figure 1 · The gates a match has to pass
0
matching words, or 1 unique
0.00
minimum score
0.00
margin over runner-up
0s
before the first booking
Taken from attribution.rs. If a candidate fails any one of these, nothing is booked and the time stays productive but unassigned.

Two extra nudges

Word matching alone ignores what you already know about the work, so two other factors adjust the score. A task marked in progress gets a quarter more weight. Dates matter too: work inside a task’s scheduled dates gets a small boost, while a task that starts more than a week from now, or is more than two weeks overdue, drops to 60%. The date comes from the same trusted clock TimerOS uses for shifts, so changing your computer’s timezone does not affect it.

Sticking with a task, and letting go

The other half of the problem is stability. A matcher that changes its mind every five seconds chops the day into thousands of fragments, which is detailed but useless.

So a match sticks. Once a task is chosen, a different task has to outscore it for two full minutes before the booking switches. A quick look at another ticket does not break up the block you are in. If a match goes thirty minutes without being confirmed again, it is released, so a task you finished at eleven does not keep collecting your afternoon.

Figure 2 · The timing rules, in seconds
How long a task must holds
20
60
120
1800
Open in appFirst bookingSwitch awayRelease
Starting is deliberately quicker than switching: picking up a task should be easy, and being pulled off it should be hard.

There is a second way in. If you have a task, incident or change request open inside TimerOS itself for twenty seconds, the time goes straight to it. No guessing is needed, because you are looking at the record. This is the only way incidents and change requests get time assigned at all.

What leaves your machine

All of this runs on your own computer, in the desktop app, which is written in Rust. The word list is built from your assigned work, and the scoring and matching happen there too.

What gets synced is a list of task IDs with a number of seconds each, in the same format as the rest of the day’s hours. Window titles are never sent: the app reads them locally and syncs only the result. The productive/idle classification works the same way, as explained in a separate post.

The matcher described here is not AI. There is no model, no server doing inference and nothing that needs a GPU. It is a fixed scoring formula: the same input always gives the same result, and it behaves the same whether your tracking mode is Automatic or Rule-based. That is why we can give you the exact thresholds in this post, and why you can predict what it will do.

How this differs from auto-tracking elsewhere

Recording activity in the background is not new: Toggl Track and Clockify both do it without a running timer. The difference is what you get at the end.

Figure 3 · Two ways to end up with a filled timesheet
Record-and-reviewMatch-on-device
What is capturedA list of the apps and sites you usedA decision about which task the time belongs to
Who does the sortingYou, afterwards, converting entries by handThe matcher, while you work
When it is unsureEverything is kept; you decide what countsNothing is booked; the time stays productive
What you do at the endBuild the timesheet from the recordCheck the exceptions, fix what is wrong
Checked against each vendor’s own documentation on 4 August 2026. Both can also start a timer automatically from a rule you set up in advance (Toggl’s can even pre-set the project), but you write the rule; the app does not work it out.

Neither approach is clearly better. Record-and-review never books anything wrong, because it never books anything; the work falls on you on Friday. Matching hands that work to the computer and accepts that it will sometimes be wrong. That is why being able to review and undo a booking matters more than the matcher itself.

What we deliberately did not do

  • No project-level fallback. When the first version could not identify a task, it booked the time to the project. We removed that five hours later, in v1.3.1. “Some time, on roughly the right project” looks plausible, and that is exactly what makes a timesheet untrustworthy.
  • No nagging. An Unassigned row shows time that matched nothing, and you can assign it in one click if you want. It does not turn red and it does not keep reminding you.
  • No hidden overwriting. A task’s hours come only from tracked time. Since v1.15.0 you can no longer type a number over them.
  • Invoicing came later, on purpose. A wrong booking becomes a wrong invoice, so matched hours stayed out of billing while the matcher was new. Since v1.15.0, time-and-materials invoices bill the tracked hours on each task, so review the matched time before you invoice.
Where to find it
Update the Windows desktop app to v1.9.0 or later. Matching is on by default. The timer bar shows which task the matcher thinks you are working on, and the Task time panel on the Performance page lets you review, reassign or unassign any booking. Task matching is included on every plan, from Freelancer up. Download TimerOS for Windows or start a free trial.
Tell us where it is wrong
The Beta label is a request for help. The thresholds in this post are our best first guess at the balance between booking too eagerly and holding back too often, and we can only tune them with real task names. If the matcher books time to the wrong task, or misses work it should have caught, please send us the example at [email protected].

We never aimed for a timesheet that fills itself in perfectly. We wanted to replace remembering with checking. You can check a list in two minutes on Friday, but you were never going to remember Tuesday.

See it on your own machine

Try it free for 14 days: add a card at signup, and nothing is charged if you cancel before the trial ends. Install the desktop app and watch it classify your day.