Archiving finished tasks
Finished tasks stay intasks.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,moveandremove-subtask --convertnever 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, andarchive.jsonmerges as data when both branches archived. - A dependency on an archived task counts as done, so
next(CLI and MCP),why,graph,listandlist --ready,tags --readyandvalidate-dependenciestreat it as finished andfix-dependenciesleaves it alone.add-dependencyon an archived task tells you to restore it first. Related and discovered-from links to an archived task are kept:fix-dependencies,remove-taskandmovedon’t treat them as dangling.
Tags and safety
- Archived tasks belong to their tag:
tags renametakes them along,tags removedeletes them with the tag, andtags copy(ortags 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.

