The Ithura Blog
Product4 min read

An undo button on the whole task, one day at a time

Ithura's Time Machine captures a canonical snapshot of every task touched in the last 24 hours, then lets any project member preview the field-by-field diff and restore the task back to that day in one click. Audited on the workspace log and on the task's own history feed. Enterprise-only.

The classic tracker failure mode: someone opens a task, edits the wrong field, saves, walks away. A week later the team notices the state is wrong, the assignee is gone, and the description says something else. There is no undo, no way to say "put it back to how it was on Tuesday". You reconstruct from Slack, from memory, from the pull request. Or you shrug.

Ithura's Time Machine puts an undo button on the whole task, one day at a time. A daily worker captures a canonical snapshot of every task touched in the last 24 hours. Any member on the project can open the Time Machine on any task, browse snapshot dates, preview the field-by-field diff, and restore the task back to that day in one click.

A Time Machine preview: five tracked fields would change
FieldBefore (snapshot)After (current)
priorityhighlow
state_idIn ProgressBacklog
assignee_ids2 items(none)
label_idsbug, uxbug
description_htmldiffers (restore to see)differs (restore to see)

What lands in a snapshot

The tracked field set is deliberately narrow: the fields you would actually miss.

  • name, description_html, priority
  • state_id, start_date, target_date, estimate_point
  • assignee_ids, label_ids, module_ids, cycle_ids, each sorted lexicographically so the snapshot hash is stable across runs.

The snapshot is sha256-hashed. If the fresh hash matches the most recent prior snapshot for the same task, the write is skipped: a task that got a comment or a subscribe / unsubscribe (both bump updated_at) does not accumulate a duplicate row.

Why the 48-hour grace window

The worker walks every issue where updated_at is within the last 48 hours. A tighter 24-hour window would miss the whole previous day whenever the cron slipped by half an hour. 48 hours plus the ON CONFLICT (issue_id, snapshot_date) DO NOTHINGguard means the worst case is one extra pass over recent rows, never a missed day.

How the restore actually works

A restore is a single transaction that rewrites the tracked field set back to the snapshot values.

  • Base fields (name, description, priority, state, dates, estimate) go back to their snapshot values via one UPDATE. Null values in the snapshot clear the live field, matching a true "put it back" contract.
  • Join tables (assignees, labels, modules, sprints) are replaced with the snapshot set: soft-delete the current rows, insert the snapshot's ids. Idempotent on repeat restores.
  • The restore is audited on the workspace log as workspace.issue.time_machine.restoredwith metadata: { issue_id, snapshot_date }, and appended to the task's activity feed so the change is visible in the standard task history.

What is not in v1

  • Sub-daily granularity. One snapshot per task per day. A spec that changes ten times in a morning collapses into one row.
  • Per-field restore. v1 restores every tracked field or none. "Only reset the assignees, keep my new description" is the next ergonomics fix.
  • HTML diff for the description. The modal notes that the description differs; v1 does not render an inline HTML diff. Restore to see the exact prior content, or use the description version history for finer control.
  • Retention pruning. Snapshots accumulate indefinitely today. A workspace-level auto-purge (delete rows older than N days) is on the roadmap.

Where Time Machine fits with the rest of Ithura

Description version history is finer-grained (every REST write is a version), and Time Machine is broader-grained (one row per day, but for the whole task). Together, the fine surface answers "what did this description say last hour" and the coarse surface answers "what did this task look like on Tuesday". Both restore into the same live row.

Dispatch and Time Machine sit at opposite ends of a task's timeline. Dispatch hands the task to a runner going forward; Time Machine puts a task back to any prior day. Both are audited, both are Enterprise, and both are the shape a tracker should have.

Related