Skip to main content

Syntax

sudocode link <from-id> <to-id> --type <relationship-type>

Description

The link command creates a typed relationship between two entities (specs or issues). Relationships are:
  • Typed - Each relationship has a specific meaning (blocks, implements, depends-on, etc.)
  • Bidirectional - Automatically tracked in both directions for graph traversal
  • Permanent - Persist across updates to entity properties
  • Graph-enabling - Power dependency resolution, planning, and visualization
Relationships are the foundation of sudocode’s graph-based planning system.
sudocode automatically detects entity types (spec or issue) by checking which exists in the database. You don’t need to specify types explicitly.

Arguments

from-id
string
required
Source entity IDExample: ISSUE-001 or SPEC-001The entity creating the relationship. sudocode automatically determines if this is a spec or issue.
to-id
string
required
Target entity IDExample: SPEC-001 or ISSUE-002The entity being referenced. sudocode automatically determines if this is a spec or issue.

Options

-t, --type
string
required
Relationship typeExample: --type implementsValid relationship types:
  • blocks - Hard blocker dependency
  • implements - Issue implements spec
  • depends-on - Soft dependency
  • references - General reference
  • related - General association
  • discovered-from - Issue discovered during implementation
See Relationship Types section for detailed explanations.

Relationship Types

blocks

Direction: FROM blocks TO Meaning: TO entity cannot proceed until FROM entity is complete. Use cases:
  • Sequential implementation tasks
  • Hard dependencies between features
  • Prerequisites that must be satisfied first
Example:
# ISSUE-002 cannot start until ISSUE-001 is done
sudocode link ISSUE-001 ISSUE-002 --type blocks
Graph behavior:
  • Blocked entities won’t appear in sudocode ready
  • Topological sorting uses blocks for execution order
  • Status of blocker affects what’s ready to work on
# Database schema must be done before API endpoints
sudocode link ISSUE-001 ISSUE-002 --type blocks
# Frontend can't proceed until API is done
sudocode link ISSUE-002 ISSUE-003 --type blocks

# Now ISSUE-001 is ready, but ISSUE-002 and ISSUE-003 are blocked
sudocode ready
# Returns: ISSUE-001

# After closing ISSUE-001, ISSUE-002 becomes ready
sudocode issue close ISSUE-001
sudocode ready
# Returns: ISSUE-002

implements

Direction: Issue → Spec Meaning: The issue implements requirements or design from the spec. Use cases:
  • Linking implementation tasks to requirements
  • Tracing code changes back to specs
  • Understanding what’s been implemented
Example:
# ISSUE-001 implements SPEC-001
sudocode link ISSUE-001 SPEC-001 --type implements
Graph behavior:
  • Specs show which issues implement them
  • Issues show which specs they fulfill
  • Enables traceability from requirement to implementation
# Create a spec
sudocode spec create "Authentication System" --priority 1

# Create implementation issues
sudocode issue create "Implement login endpoint"
sudocode issue create "Implement registration endpoint"

# Link issues to spec
sudocode link ISSUE-001 SPEC-001 --type implements
sudocode link ISSUE-002 SPEC-001 --type implements

# Now SPEC-001 shows both issues implement it
sudocode spec show SPEC-001
# Incoming Relationships:
#   ISSUE-001 → implements
#   ISSUE-002 → implements

depends-on

Direction: FROM depends on TO Meaning: FROM entity needs context/output from TO entity, but it’s not a hard blocker. Use cases:
  • Informational dependencies
  • Context that should be read but doesn’t block work
  • Related work that informs implementation
Example:
# ISSUE-003 depends on SPEC-002 for guidance
sudocode link ISSUE-003 SPEC-002 --type depends-on
Graph behavior:
  • Doesn’t block execution (entity still appears in ready queue)
  • Provides context for agents working on the issue
  • Can be used for soft ordering hints
# Frontend issue depends on API spec for context, but can start work
sudocode link ISSUE-005 SPEC-010 --type depends-on

# ISSUE-005 is still ready (not blocked)
sudocode ready
# Returns: ISSUE-005 (even though it depends on SPEC-010)

# Agent can read SPEC-010 for guidance while implementing ISSUE-005

references

Direction: FROM references TO Meaning: General contextual link without specific blocking or implementation semantics. Use cases:
  • Cross-referencing related entities
  • Creating links between documentation
  • Default type for [[ID]] syntax without explicit type
Example:
# SPEC-001 references SPEC-010 for context
sudocode link SPEC-001 SPEC-010 --type references
Graph behavior:
  • No blocking or ordering implications
  • Purely for navigation and context
  • Automatic type for cross-references without explicit type
# Authentication spec references API design patterns
sudocode link SPEC-001 SPEC-010 --type references

# Issue references another related issue for context
sudocode link ISSUE-005 ISSUE-020 --type references

# Helps developers understand related work and context
Direction: Bidirectional (FROM and TO are related) Meaning: Entities share context or are associated without a specific directional relationship. Use cases:
  • Parallel work on related features
  • Entities in the same domain
  • Context grouping without direction
Example:
# ISSUE-005 and ISSUE-006 are related (both auth work)
sudocode link ISSUE-005 ISSUE-006 --type related
Graph behavior:
  • No blocking or ordering
  • Useful for finding peripheral context
  • Can group related work for visualization
# Two issues working on related authentication features
sudocode link ISSUE-010 ISSUE-011 --type related

# Specs covering related architectural domains
sudocode link SPEC-005 SPEC-006 --type related

# Helps discover related work in same area

discovered-from

Direction: New Issue → Source Issue Meaning: A new issue was discovered while working on another issue. Use cases:
  • Tracking scope creep
  • Understanding how issues spawn new work
  • Tracing problem discovery during implementation
Example:
# ISSUE-010 was discovered while working on ISSUE-005
sudocode link ISSUE-010 ISSUE-005 --type discovered-from
Graph behavior:
  • Shows issue genealogy
  • Helps understand how work expands
  • Can identify issues that frequently spawn new issues
# While implementing login, discover password reset is also needed
sudocode issue create "Add password reset flow"
sudocode link ISSUE-010 ISSUE-005 --type discovered-from

# Shows ISSUE-010 was discovered from ISSUE-005
sudocode issue show ISSUE-010
# Outgoing Relationships:
#   discovered-from → ISSUE-005

Examples

Create a simple relationship:
sudocode link ISSUE-001 SPEC-001 --type implements
✓ Created relationship
ISSUE-001 implements → SPEC-001

Block an Issue

Prevent work until dependency is done:
sudocode link ISSUE-001 ISSUE-002 --type blocks
✓ Created relationship
ISSUE-001 blocks → ISSUE-002
Interpretation: ISSUE-002 is blocked by ISSUE-001. ISSUE-002 cannot proceed until ISSUE-001 is closed. Connect implementation tasks to requirements:
sudocode link ISSUE-001 SPEC-001 --type implements
sudocode link ISSUE-002 SPEC-001 --type implements
sudocode link ISSUE-003 SPEC-001 --type implements
✓ Created relationship
ISSUE-001 implements → SPEC-001
✓ Created relationship
ISSUE-002 implements → SPEC-001
✓ Created relationship
ISSUE-003 implements → SPEC-001

Create Dependency Chain

Model sequential dependencies:
# Database schema first
sudocode link ISSUE-001 ISSUE-002 --type blocks

# Then API endpoints
sudocode link ISSUE-002 ISSUE-003 --type blocks

# Then frontend
This creates: ISSUE-001 → ISSUE-002 → ISSUE-003

Cross-Reference Specs

Link related specifications:
sudocode link SPEC-001 SPEC-010 --type references
✓ Created relationship
SPEC-001 references → SPEC-010

Track Issue Discovery

Document when issues are discovered:
sudocode link ISSUE-020 ISSUE-015 --type discovered-from
✓ Created relationship
ISSUE-020 discovered-from → ISSUE-015

JSON Output

Get machine-readable output:
sudocode --json link ISSUE-001 SPEC-001 --type implements
{
  "from": "ISSUE-001",
  "to": "SPEC-001",
  "type": "implements",
  "success": true
}

Viewing Relationships

After creating relationships, view them with show commands:
# View issue relationships
sudocode issue show ISSUE-001

# View spec relationships
sudocode spec show SPEC-001
The output includes:
  • Outgoing Relationships - From this entity to others
  • Incoming Relationships - From others to this entity

Choosing the Right Relationship Type

Use this decision matrix:
1

Is it a hard blocker?

Use blocks if FROM must complete before TO can proceed
2

Is it implementing requirements?

Use implements for issue → spec implementation links
3

Is it informational context?

Use depends-on for soft dependencies or references for general links
4

Is it associative?

Use related for bidirectional associations without specific semantics
5

Was it discovered during work?

Use discovered-from to track issue genealogy

Common Workflows

Spec-Driven Development

1

Create a spec

sudocode spec create "User Dashboard" --priority 1
2

Create implementation issues

sudocode issue create "Build dashboard layout"
sudocode issue create "Add data visualizations"
sudocode issue create "Implement filters"
3

Link issues to spec

sudocode link ISSUE-001 SPEC-001 --type implements
sudocode link ISSUE-002 SPEC-001 --type implements
sudocode link ISSUE-003 SPEC-001 --type implements
4

Model dependencies

# Layout must be done before visualizations
sudocode link ISSUE-001 ISSUE-002 --type blocks

Modeling Complex Dependencies

1

Create all issues

sudocode issue create "Database schema"      # ISSUE-001
sudocode issue create "API endpoints"        # ISSUE-002
sudocode issue create "Frontend components"  # ISSUE-003
sudocode issue create "Integration tests"    # ISSUE-004
2

Model blockers

sudocode link ISSUE-001 ISSUE-002 --type blocks
sudocode link ISSUE-002 ISSUE-003 --type blocks
sudocode link ISSUE-003 ISSUE-004 --type blocks
3

Find ready work

sudocode ready
# Returns: ISSUE-001 (only unblocked issue)

Discovering and Linking New Work

1

Start work on issue

sudocode issue update ISSUE-005 --status in_progress
2

Discover new requirement

While implementing, realize password reset is needed
3

Create new issue

sudocode issue create "Add password reset flow"
4

Link as discovered

sudocode link ISSUE-010 ISSUE-005 --type discovered-from

Relationship Best Practices

# Clear sequential dependencies
sudocode link ISSUE-001 ISSUE-002 --type blocks

# Implementation links to specs
sudocode link ISSUE-001 SPEC-001 --type implements

# Soft context dependencies
sudocode link ISSUE-005 SPEC-002 --type depends-on
# Don't create circular dependencies
sudocode link ISSUE-001 ISSUE-002 --type blocks
sudocode link ISSUE-002 ISSUE-001 --type blocks  # ❌ Circular!

# Don't use 'blocks' for soft context
sudocode link ISSUE-003 SPEC-005 --type blocks  # ❌ Use depends-on

# Don't over-link everything as 'related'
# Only link when there's actual shared context

Understanding Bidirectional Tracking

All relationships are automatically tracked in both directions:
# Create a relationship
sudocode link ISSUE-001 SPEC-001 --type implements
From ISSUE-001 perspective:
sudocode issue show ISSUE-001
# Outgoing Relationships:
#   implements → SPEC-001 (spec)
From SPEC-001 perspective:
sudocode spec show SPEC-001
# Incoming Relationships:
#   ISSUE-001 (issue) → implements
This enables:
  • Forward traversal - What does this entity depend on/reference?
  • Backward traversal - What depends on/references this entity?
  • Graph queries - Find all connected entities
  • Impact analysis - What’s affected if this changes?

Common Questions

Yes! Entities can have multiple relationship types between them:
sudocode link ISSUE-001 SPEC-001 --type implements
sudocode link ISSUE-001 SPEC-001 --type depends-on
Both relationships are tracked independently.
  • blocks - Hard dependency, prevents work from starting (affects ready query)
  • depends-on - Soft dependency, provides context but doesn’t prevent work
Use blocks for technical prerequisites, depends-on for informational context.
There’s currently no unlink command in the CLI. To remove relationships:
  1. Edit the JSONL file directly
  2. Run sudocode sync to update the database
  3. Or update the database directly using SQL
No, sudocode validates that both entities exist before creating the relationship. You’ll get an error if either ID doesn’t exist.
Relationships are not automatically deleted. They become orphaned, which can cause broken links. Best practice: clean up relationships before deleting entities.

Troubleshooting

Cause: One or both entity IDs don’t existSolution: Verify both IDs exist:
sudocode spec list
sudocode issue list
Cause: The relationship type isn’t validSolution: Use one of: blocks, implements, depends-on, references, related, discovered-from
sudocode link ISSUE-001 SPEC-001 --type implements
Cause: Sync or cache issueSolution: Run sync:
sudocode sync
sudocode issue show ISSUE-001
Cause: Created circular blocks relationshipsSolution: Review your dependency chain. Use depends-on for soft dependencies that don’t need strict ordering.

Next Steps

1

Create entities

sudocode spec create "My Feature"
sudocode issue create "Implement X"
2

Link them

sudocode link ISSUE-001 SPEC-001 --type implements
3

View relationships

sudocode spec show SPEC-001
sudocode issue show ISSUE-001
4

Find ready work

sudocode ready

Relationships Concept Guide

Learn more about relationships and graph-based planning