Inside the Protocol: What an AI Timesheet Optimizer Actually Does
"AI rewrites your timesheet" is the kind of sentence that should make a professional nervous. Your hours are legal documents in waiting — they back invoices, sometimes contracts, occasionally disputes. Handing them to a language model and hoping for the best is not a workflow. So this is a tour of what actually happens inside taime, including the parts where we deliberately don't trust our own AI.
The protocol, not a prompt
Every optimization run starts from your protocol — a configuration you control, not a canned prompt we wrote once and hope fits everyone.
Granularity decides the rhythm of the output: 15-minute blocks read like a consultancy, 5-minute blocks read like a log file. Gap management decides what happens to the holes in your day — leave them, or account for them as the administrative work they usually were, above a threshold you set. Task splitting breaks a four-hour "worked on project" block into the phases a client can actually read. Keyword locks are the do-not-touch list: any entry matching a locked keyword passes through byte-identical. Some rows are sacred — a deposition, a compliance review — and the machine's job is to leave them alone.
The model rewrites your shorthand into professional register along the way: the typo-ridden "Kontola reportu" becomes a clean line about report review; "call w/ P." becomes a description someone will pay for. Same work, dressed for the invoice.
Where we stopped trusting the model
Here is the part most AI products don't tell you. We benchmarked our pipeline across models and fixtures, repeatedly, against real exported timesheets. The lesson was consistent: language models are excellent at prose and unreliable at promises. So the promises moved out of the prompt and into code.
The prompt asks, the code guarantees. After the model responds, a deterministic layer checks its work. Locked entries are restored from the original file, not from the model's memory of it. Daily totals are capped in code — if the output would exceed your target day, generated entries are dropped until it doesn't. Gap-fills the model forgot are added by the server, computed from your actual data. Duration-only rows are reconciled so the minutes you imported are exactly the minutes you export.
The summary can't lie. Early on we caught the model claiming it had filled gaps it never filled. Now the run summary is assembled from what actually happened in the pipeline — counted, not narrated.
Your data is treated as data. The pipeline runs behind an input trust boundary: text inside your timesheet is never treated as instructions to the model. We maintain an adversarial test suite that tries to smuggle commands in through entry descriptions, and passing it is a release requirement.
What we refuse to do
taime does not invent work. Every generated entry is flagged internally as generated; everything else traces back to a row you logged. The point is not to fabricate hours — it's to stop the real ones from evaporating in transmission. Presentation, not fiction.
That's the whole trick, honestly. Not a bigger model — a shorter leash.
Curious what your own protocol would look like? The first day is free.