task-graph-repair — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited task-graph-repair (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Diagnose and fix common issues: orphaned tasks, broken dependencies, stale claims, disconnected agents, and data inconsistencies.
Prerequisite: Understand task-graph-basics for tool reference.
# 1. Connect with repair capabilities
connect(name="repair-agent", tags=["repair", "admin"])
→ agent_id
# 2. Run diagnostics
list_tasks(format="markdown") # Overview
list_tasks(blocked=true) # Blocked tasks
list_agents(format="markdown") # Agent status
# 3. Fix issues as discovered
# (See specific repair procedures below)Run these queries to identify issues:
| Query | Looking For |
|---|---|
list_tasks(blocked=true) | Tasks stuck on deps |
list_tasks(status="working") | Potentially stale work |
list_agents() | Disconnected/stale agents |
list_marks() | Abandoned file marks |
list_tasks(parent="null") | Unexpected root tasks |
Symptoms: Tasks with no parent that shouldn't be root tasks.
Diagnosis:
# Find all root tasks
list_tasks(parent="null")
# Identify which are intentional vs orphaned
# Orphaned = was child, parent deleted without cascadeRepair Options:
# Option A: Re-parent to correct parent
update(agent=agent_id, task=orphan_id, parent=correct_parent_id)
# Option B: Delete if no longer needed
delete(task=orphan_id, cascade=true)
# Option C: Make intentional root
# (No action needed, just document)Symptoms: Task blocked by non-existent task, or circular dependency.
Diagnosis:
# Find blocked tasks
list_tasks(blocked=true)
# For each, check blockers exist
get(task=blocked_task_id) # Look at blockedBy field
# Try to fetch each blocker
get(task=blocker_id) # Will fail if deletedRepair:
# Remove reference to deleted blocker
unblock(blocker=deleted_task_id, blocked=stuck_task_id)
# For circular deps (rare, should be rejected):
# Break the cycle by removing one edge
unblock(blocker=task_a, blocked=task_b)Symptoms: Task claimed by agent that disconnected or crashed.
Diagnosis:
# Find claimed tasks
list_tasks(status="working")
# Check agent status
list_agents()
# Look for:
# - last_heartbeat far in past
# - agent not in list (disconnected)Repair:
# Option A: Force-claim for yourself or another agent
claim(agent=new_agent_id, task=stale_task_id, force=true)
# Option B: Release back to pool
release(agent=your_agent_id, task=stale_task_id, state="pending")
# Note: You can release tasks you don't own with force
# Option C: If work was partially done
# Add handoff notes first
attach(task=task_id, name="handoff",
content="Previous agent disconnected. Work state: ...")
release(agent=your_agent_id, task=task_id, state="pending")Symptoms: Files locked by disconnected agents.
Diagnosis:
# List all marks
list_marks()
# Cross-reference with active agents
list_agents()
# Marks by agents not in list = abandonedRepair:
# Unmark the file (as repair agent)
unmark_file(agent=your_agent_id, file=marked_file,
reason="Unmarked by repair: original agent disconnected")Symptoms: Need to reopen completed/cancelled task.
Note: Terminal states (completed, cancelled) have no exits by default.
Repair Options:
# Option A: Create new task instead
create(title="Reopen: Original Title",
description="Continuation of task X which was closed prematurely")
# Option B: If custom states configured, add exit
# (Requires config change - see task-graph-mcp docs)
# Option C: Direct DB intervention (last resort)
# Not recommended - use task-graph toolsSymptoms: Task tree has gaps or unexpected structure.
Diagnosis:
# Get full tree
get(task=root_id, children=true, format="markdown")
# Check for:
# - Missing intermediate parents
# - Tasks at wrong level
# - Sibling order issuesRepair:
# Fix parent reference
update(agent=agent_id, task=misplaced_id, parent=correct_parent_id)
# Note: Direct parent updates may need DB access
# Alternative: recreate task in correct location
new_task = create(parent=correct_parent, ...)
# Copy attachments
# Delete old task
delete(task=old_task_id)Symptoms: time_actual_ms is 0 for completed tasks.
Diagnosis:
# Check state history
get_state_history(task=task_id)
# Should show transitions through timed states
# If missing working, time wasn't trackedRepair:
# Can't retroactively add time tracking
# But can add estimated time to attachment
attach(task=task_id, name="time-estimate",
content="Estimated actual time: 2 hours",
mime="text/plain")
# For future: ensure workers use claim() which sets workingSymptoms: Same work represented multiple times.
Diagnosis:
# Search for similar titles
list_tasks(format="markdown")
# Manually identify duplicates
# Or: check attachments for source IDs (if migrated)
attachments(task=task_id, content=true)Repair:
# 1. Identify authoritative task (most progress)
# 2. Merge information via attachments
attach(task=keep_id, name="merged-from",
content="Merged from task {delete_id}: {notes}")
# 3. Update any dependencies pointing to duplicate
# Find tasks blocked by duplicate
# Point them to kept task
unblock(blocker=duplicate_id, blocked=dependent_id)
block(blocker=kept_id, blocked=dependent_id)
# 4. Delete duplicate
delete(task=duplicate_id, cascade=false) # Don't delete children┌─────────────────────────────────────────────────────┐
│ 1. CONNECT AS REPAIR AGENT │
│ connect(tags=["repair", "admin"]) │
├─────────────────────────────────────────────────────┤
│ 2. RUN FULL DIAGNOSTIC │
│ • list_tasks (all statuses) │
│ • list_tasks(blocked=true) │
│ • list_agents │
│ • list_marks │
├─────────────────────────────────────────────────────┤
│ 3. CATEGORIZE ISSUES │
│ • Orphaned tasks │
│ • Broken dependencies │
│ • Stale claims │
│ • Abandoned locks │
│ • Other inconsistencies │
├─────────────────────────────────────────────────────┤
│ 4. FIX IN ORDER │
│ a. File locks (unblocks agents) │
│ b. Stale claims (frees tasks) │
│ c. Broken deps (unblocks tasks) │
│ d. Orphaned tasks (cleans structure) │
├─────────────────────────────────────────────────────┤
│ 5. VERIFY │
│ Re-run diagnostics to confirm fixes │
├─────────────────────────────────────────────────────┤
│ 6. DOCUMENT │
│ Attach repair log to root task │
└─────────────────────────────────────────────────────┘| Issue | Prevention |
|---|---|
| Orphaned tasks | Always use cascade=true when deleting parents |
| Stale claims | Implement heartbeat monitoring |
| Abandoned locks | Release files before disconnect |
| Broken deps | Validate blockers exist before block() |
| Duplicates | Check for existing before create() |
Document repairs for audit trail:
# Repair Log - {timestamp}
## Issues Found
1. {issue_type}: {description}
2. ...
## Actions Taken
1. {action}: {details}
- Before: {state}
- After: {state}
2. ...
## Verification
- [ ] No blocked tasks without valid blockers
- [ ] No stale claims
- [ ] No abandoned file locks
- [ ] Hierarchy consistent
## Notes
{any additional observations}# Attach to root task
attach(task=root_id, name="repair-log-{date}",
content=repair_log, mime="text/markdown")| Skill | When to Use |
|---|---|
task-graph-basics | Tool reference, task trees |
task-graph-reporting | Verify data integrity |
task-graph-migration | Re-migrate if severe corruption |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.