Two Sync Engines, Two Different Jobs
Workwarrior ships two GitHub sync engines. They’re complementary, not redundant, and understanding the distinction matters for how you configure each one.
Bugwarrior — one-way pull from 20+ issue tracking services into TaskWarrior.
ww github-sync — two-way bidirectional sync between individual tasks and GitHub issues.
Use both. They handle different parts of the problem.
Bugwarrior: Pull Everything
Bugwarrior is a pull tool. Configure it with API credentials for your services — GitHub, GitLab, Jira, Trello, Bitbucket, and 17 more — and i pull brings all your open issues into TaskWarrior as tasks.
ww issues custom # Configure services interactively
i pull # Pull from all configured services
i status # Show what was pulled
The tasks it creates carry injected UDAs: githubissue, githuburl, githubrepo, githubauthor. These are tagged [github] in the UDA source registry — you can see them with ww profile uda list.
Bugwarrior is strictly one-way. It reads from the service and writes to TaskWarrior. Changes you make to a bugwarrior-created task in TaskWarrior don’t flow back to GitHub. That’s where github-sync comes in.
ww github-sync: Two-Way on Selected Tasks
The two-way sync engine links individual TaskWarrior tasks to individual GitHub issues. Once linked, changes flow in both directions: update the task locally, it updates the issue. Comment on the issue, the annotation appears on the task.
ww issues enable <task> <issue#> <org/repo> # Link
ww issues sync # Two-way sync all linked
ww issues push # Push local → GitHub only
What syncs bidirectionally:
- Description ↔ Title
- Status ↔ State (pending/started → OPEN, completed/deleted → CLOSED)
- Priority ↔ Labels (H/M/L → priority:high/medium/low)
- Tags ↔ Labels
- Annotations ↔ Comments (with prefixes to prevent sync loops)
What pulls only (GitHub → TaskWarrior):
- Issue number, URL, repo, author, created date, closed date
Conflict resolution is last-write-wins with a configurable conflict window. If both sides changed within the window, the sync reports the conflict rather than silently overwriting.
The Fragility Register
The sync engine is the highest-risk part of the codebase. Ten files in lib/. Classified HIGH FRAGILITY.
Getting it wrong means data loss in two places simultaneously: a task annotation deleted that was actually a comment on a critical issue, a status change propagated incorrectly that closes an issue that shouldn’t be closed. These failures are hard to detect and harder to reverse.
The development protocol for these files: extended risk brief before any change, explicit write scope, Verifier sign-off before merge, integration tests required. This isn’t excessive — it’s proportionate to the failure modes.
Using Them Together
The intended workflow:
- Configure Bugwarrior to pull from all your services. Run
i pullto get all your issues as tasks. - Identify the tasks you’re actively working and want to keep in sync. Run
ww issues enableon those. - Work normally.
i pullrefreshes the full issue list.ww issues synckeeps your linked tasks bidirectionally current.
The Bugwarrior-created tasks and the github-sync-linked tasks can coexist in the same TaskWarrior profile. Bugwarrior stamps its tasks with the [github] source badge on the UDA. github-sync manages its own state file. They don’t interfere with each other.