Skip to main content

Archiving finished tasks

Finished tasks stay in tasks.json until you archive them. taskgraph archive moves them to .taskgraph/tasks/archive.json, one section per tag, so list, validation and agent context only carry the work that is still open.
--tag <tag> picks another tag, and --format json prints the tasks moved (keys in JSON Output). MCP clients use the archive_tasks tool (olderThanDays, dryRun, restore) in the all tier.

Which tasks move

The age is the task’s last update (updatedAt, or a subtask’s when later). A finished task with no update time was finished before TaskGraph recorded one, so it counts as old enough. The default age comes from global.archiveAfterDays (30 when unset; see Configuration).

IDs and dependencies

  • Archived tasks keep their IDs: add-task, parse-prd, move and remove-subtask --convert never hand an archived ID to a new task, even after a restore. The merge driver doesn’t either: a task another branch added under an ID archived here gets the next free ID, and archive.json merges as data when both branches archived.
  • A dependency on an archived task counts as done, so next (CLI and MCP), why, graph, list and list --ready, tags --ready and validate-dependencies treat it as finished and fix-dependencies leaves it alone. add-dependency on an archived task tells you to restore it first. Related and discovered-from links to an archived task are kept: fix-dependencies, remove-task and move don’t treat them as dangling.

Tags and safety

  • Archived tasks belong to their tag: tags rename takes them along, tags remove deletes them with the tag, and tags copy (or tags add --copy-from) copies them, so the copy’s dependencies on them still count as done and their IDs stay reserved there too.
  • Archive and restore take the same lock as every other write to tasks.json, so a change another session saves at the same time isn’t lost. Every change to archive.json also takes its own lock and replaces the file in one step.
  • Archive writes archive.json before tasks.json, and restore writes tasks.json first. If the process stops between the two writes, the task is in both files, never in neither. The copy in tasks.json is the one that counts.