OpenSpec TD Sync
Sync the current state of td tasks to openspec format, making td the source of truth while maintaining human-readable openspec artifacts.
Purpose
This skill bridges td (task management source of truth) with openspec (spec-driven development filesystem). When requested, it:
- •Queries the current state of work from
td(issues, tasks, epics, decisions) - •Formats this as an openspec artifact (typically
tasks.md) - •Keeps the filesystem synchronized with the actual work state
TD Structure it Syncs:
Epic → Proposal Feature/Bug → Spec Feature/Bugs → Requirement Tasks
This enables:
- •
tdto remain the authoritative task tracker - •Agents to work with
tdCLI while maintaining readable SDD filesystem - •Handoffs between sessions/agents to include openspec context
- •Easy auditing of what was planned vs. what actually happened
When to Use
Use this skill when:
- •Starting a new openspec change to establish td tasks for the first time
- •Updating tasks.md during or after implementation to reflect current td state
- •Handing off work between agents/sessions (include synchronized openspec state)
- •Creating a human-readable snapshot of agent work for auditing
Workflow
Step 1: Identify the Change Context
First, understand which change you're syncing tasks for:
# If a specific change name is provided: # - Use that change name and get its epic_id from proposal.md # If not specified, ask the user: # "Which change should I sync tasks for? # Provide the change name (e.g., 'auth-feature')."
Important: You need:
- •Change name (to locate openspec/changes/<name>/)
- •Epic ID (read from proposal.md frontmatter)
- •Proposal Feature/Bug ID (read from proposal.md frontmatter)
These are the context needed to query and sync the correct td structure.
Step 2: Query Current TD State
# List all child issues for the proposal feature/bug td list --parent "<proposal_feature_id>" --json # Or query by epic to see full hierarchy td list --epic "<epic-id>" --json # Get spec feature/bugs (children of proposal) td list --filter "parent=<proposal_feature_id> AND (type=feature OR type=bug)" --json # Get requirement tasks (children of specs, labeled=requirement) td list --filter "label=requirement" --json
Parse the JSON output to understand:
- •Issue IDs and titles
- •Issue type (feature, bug, task)
- •Issue status (open, in_progress, in_review, done)
- •Issue assignees/implementers
- •Parent relationships (critical for hierarchy)
- •Labels (use 'requirement' to identify requirement tasks)
- •Dependencies between issues
Structure: For spec-td schema:
Epic (td-xxxxx)
└── Proposal Feature/Bug (td-proposal, parent=epic_id)
├── Spec Feature/Bug (td-spec1, parent=td-proposal)
│ ├── Task (td-spec1-req1, parent=td-spec1, label=requirement)
│ └── Task (td-spec1-req2, parent=td-spec1, label=requirement)
└── Spec Feature/Bug (td-spec2, parent=td-proposal)
└── Task (td-spec2-req1, parent=td-spec2, label=requirement)
Step 3: Organize Spec Feature/Bugs into Phases
From the td data, organize the SPEC feature/bugs (type=feature or type=bug, parent=proposal_feature_id):
- •Each spec feature/bug becomes a phase/section (corresponds to specs/<cap>/spec.md)
- •Include child requirement tasks under each spec feature/bug
- •Order by implementation order or dependency
Important: Do NOT include the proposal feature/bug itself as a phase—only its child spec feature/bugs.
Step 4: Format as OpenSpec Tasks Artifact
Create or update tasks.md in the change directory following the schema template.
Structure the output as groups/phases based on spec feature/bugs:
# Tasks ## 1. User Authentication API - Status: Not Started / In Progress / Blocked / Done - Type: Spec Feature (td-spec1) - Assignee: <agent-name> - Tasks: - [ ] td-spec1-req1: Requirement title - [x] td-spec1-req2: Requirement title (completed) ## 2. API Documentation - Status: Not Started / In Progress / Blocked / Done - Type: Spec Feature (td-spec2) - Assignee: <agent-name> - Tasks: - [ ] td-spec2-req1: Requirement title
Key mappings:
- •td
type=featureortype=bug(parent=proposal_feature_id) → spec phase/section - •td
type=taskwithlabel=requirement→ requirement task under a spec - •td
status=done→[x](completed checkbox) - •td
status=in_progress→ may still show as[ ]until marked done - •td
status=open→[ ](uncompleted checkbox) - •td assignee → include in section header as "Assignee"
Step 5: Include Supplemental Information
If appropriate, include:
## Decisions Made (from td notes/logs) - Decision: <description> (td-xxxx) - Decision: <description> (td-yyyy) ## Blockers or Notes - Blocker: <description> (td-xxxx) - Note: <description>
Step 6: Write or Update tasks.md
Write the formatted output to openspec/changes/<change-name>/tasks.md
If the file already exists, preserve the structure and update task checkboxes and phase status.
Integration with OpenSpec Commands
This skill is used internally by:
- •
opsx-apply- After marking tasks complete, optionally sync withtdstate - •
opsx-archive- Verify final task state matches td before archiving - •
opsx-continue- Ensure tasks.md reflects current td state
Example Output
Given these td issues for epic td-root1 with proposal feature td-proposal:
td-root1 "User API Platform" [epic]
└─ td-proposal "Implement user API system" [feature] (parent: td-root1) ← proposal
├─ td-spec1 "User endpoints specification" [feature] (parent: td-proposal) ← spec
│ ├─ td-spec1-req1 "Add /users endpoint" [task, label=requirement] [in_progress]
│ └─ td-spec1-req2 "Add authentication" [task, label=requirement] [open]
│
└─ td-spec2 "API documentation specification" [feature] (parent: td-proposal) ← spec
└─ td-spec2-req1 "Document authentication" [task, label=requirement] [open]
The output would be:
# Tasks ## 1. User endpoints specification - Status: In Progress - Type: Spec Feature (td-spec1) - Assignee: backend-agent - Tasks: - [ ] td-spec1-req1: Add /users endpoint - [ ] td-spec1-req2: Add authentication ## 2. API documentation specification - Status: Not Started - Type: Spec Feature (td-spec2) - Assignee: docs-agent - Tasks: - [ ] td-spec2-req1: Document authentication
Note: The proposal feature/bug (td-proposal) is NOT included as a phase in tasks.md—only the spec feature/bugs and their requirement tasks.
Implementation Notes
- •Always use
--jsonflag when querying td for structured parsing - •Preserve td task IDs in the output for traceability
- •Keep task descriptions concise (copy from td titles)
- •Map task status to checkbox state (not arbitrary)
- •When updating existing tasks.md, maintain the phase structure if it exists
- •Don't create new phases unless the td structure suggests it