Engineering
Why MinuteShark AI Never Writes Until You Confirm
AI time tracking confirmation is not a polish item. It is the product.
MinuteShark AI can add a client, start a timer, or log the hour you forgot after a call. Those actions become invoices, retainers, and the story you tell a client about where the week went. If an assistant writes that data silently, you do not have a copilot. You have a liability.
The rule we shipped: nothing is written until you tap Confirm on a proposal card. You can edit the card first. Many actions can be reverted from chat if you change your mind.
This post is about that confirmation UX — why we built it that way on Ionic, Angular, Capacitor, and Firebase, and why “just apply it” would have been faster to demo and worse to bill from.
Why billing data cannot be a best guess
A chatbot that answers “how do I log time?” can be wrong and you still have an undo: you close the thread. A workspace assistant that does the logging is different. The blast radius is a timesheet line that may later sit on a PDF.
Freelancers already distrust tools that “help” by inferring. Employer-grade trackers guess from screenshots and app usage. Passive calendar tools guess from meeting titles. We did not want MinuteShark AI to join that club. The public introduction of MinuteShark AI already promised action-with-control. Confirmation is how that promise stays true after the demo glow wears off.
Three failure modes we refused to ship:
- Wrong task, right duration. “Log an hour on wireframes” is easy to resolve to the wrong client if two projects share a nickname.
- Right task, wrong day. “Yesterday’s standup” depends on timezone, work-week bounds, and whether “yesterday” still means the calendar date you think it does at 12:10 a.m.
- Destructive cleanup. Rename, move, and delete look like housekeeping until they scramble a report you already sent.
A confirmation card makes those mistakes visible while they are still cheap.
The confirm-card flow we actually run
On web, MinuteShark AI lives as a floating widget. On iOS and Android (Capacitor 7 wrapping the same Angular 16 app), it is a full chat. The mutation path is the same.
Propose → edit → confirm
You type or speak. The assistant gathers workspace context — timezone, today, active timer, recent activity, visible clients/projects/tasks, permissions — and returns a proposal card, not a write.
- Propose. A card states the action in human language: log 1 hour on Homepage mockups for today; add client Contoso; start a timer on wireframes.
- Edit. You can fix the duration, date, or target before anything hits Firestore.
- Confirm. Only then does a Firebase Function commit the change. Cancel leaves the workspace untouched.
If the request is ambiguous, you get a short picker instead of a confident wrong write. If it is out of scope (weather, general trivia), the assistant stays a workspace copilot and does not pretend to be the internet.
Voice on mobile adds one extra human checkpoint: microphone → transcript review → send. We do not pipe raw audio into a write. You still confirm the card.
Why the extra tap is a latency feature, not a tax
Engineers feel the delay. The model has to return a structured proposal. The card has to render. The user has to look at it. Compared with a silent tool call, that is slower.
Users feel something else: safety that is fast enough. If the card appears before they look away, confirmation is cheaper than hunting through History later. If the card is sluggish, people start rubber-stamping — which defeats the design. So we treat time-to-card as a product bug, the same way we treat a wrong tool pick as an accuracy bug.
That is why the stack conversation inside ElementPragma is usually about round-trip feel, not about stuffing more autonomy into the first token:
- Ionic + Angular 16 for a keyboard-first web app that can also ship as iOS and Android.
- Capacitor 7 so the chat and timer widgets are one codebase, with native extras (voice, Live Activities) where they belong.
- Firebase Auth, Firestore, and Functions so the confirm tap is a real commit, not a local optimistic fake that later disagrees with another device.
- Algolia for the dashboard search that still starts timers when you are not in the mood to chat.
The assistant proposes. The database changes when a person says so. Sync then shows the same workspace on phone and laptop. That is boring on purpose.
What the card is allowed to do — and what it is not
Confirmation is not a fig leaf over unbounded agency. The action catalog is the freelance workspace: clients, projects, tasks, time entries, timers, notes, assignments, close/open on tasks, reports with filters. It can answer how much you tracked today or this week from supplied stats. It does not secretly log time in order to “answer” that question.
It also does not silently “clean up” your day. No idle-time invention. No screenshot story. No background rewrite of durations. If you want 0.1-hour rounding, that is a workspace setting that rounds up for billing while keeping the original duration — a human-configured rule, not an AI improvisation. The time rounding guide is the source of truth for that behavior.
Permissions still apply. If you cannot manage a client, the assistant should not present a confirm card that pretends you can. A Regular User and an Admin should not get the same superpowers from a friendly sentence.
Revert is the second seatbelt
Confirm is the first seatbelt. Revert is the second. After a write, many actions can be undone from the same conversation. Chat history is kept for up to seven days, with multiple threads, so “wait, that was the other Contoso project” can still be repaired without a forensic slog through History.
We would rather you revert a confirmed card than train the model to be braver. Bravery is how you ship a 14-hour timer onto an invoice because the assistant was “helpful.”
How we evaluate this (without turning it into a model beauty contest)
We already wrote about not chasing the newest LLM. Confirmation UX is a better evaluation target: did the card show the right action, with the right fields, fast enough that a consultant would actually look at it?
Useful checks:
- Does “log 30 minutes on yesterday’s standup” land on the standup task, yesterday, 30 minutes — not today, not an hour, not a similarly named internal meeting?
- Does a bulk-add of clients arrive as a list you can still refuse?
- Does “start a timer on the wireframes task” refuse to start a second timer if one is already running?
- Does a report request open Reports with filters instead of fabricating a CSV in chat?
Those are product tests. They happen to use a model. They are not a leaderboard.
What this means if you are building something similar
If your AI can move money-adjacent records, put a person in the loop on the write path. Show the proposed mutation in the user’s language. Let them edit. Persist only on confirm. Offer revert. Keep the assistant inside the domain — here, a client → project → task → time-entry workspace — so it does not have to be omniscient.
MinuteShark AI is included on every plan, with monthly message allowances. The confirmation card is included too. We would rather spend a message on a card you reject than spend your Friday explaining a line item nobody approved.
If you want the wider “assistants that do stuff” framing, that piece already exists. This one is narrower: the write does not happen until you say it does.