Bidirectional Task ↔ User Story Linking
Status: Production Ready Feature: Automatic bidirectional traceability between tasks and user stories
Overview
SpecWeave automatically creates bidirectional links between tasks and user stories during living docs sync. This provides complete traceability in both directions:
- Forward Links (US → Tasks): User stories link to all implementing tasks
- Reverse Links (Tasks → US): Tasks link back to their user story (automatic!)
How It Works
Automatic During /sw:done
When you complete an increment:
/sw:done 0031
SpecWeave automatically:
- Extracts user stories from
spec.md - Writes user story files to
.specweave/docs/internal/specs/{project}/{feature}/ - Parses tasks.md for AC-IDs (e.g.,
AC-US1-01) - Creates task → user story mapping
- Injects reverse links into tasks.md
What Gets Added
Before (no bidirectional link):
### T-001: Implement User Login
**AC**: AC-US1-01, AC-US1-02, AC-US1-03
**Test Plan** (BDD):
- **Given** valid credentials → **When** login → **Then** receive JWT token
After (WITH bidirectional link):
### T-001: Implement User Login
**User Story**: [US-001: User Authentication](../../docs/internal/specs/default/auth-service/us-001-user-authentication.md)
**AC**: AC-US1-01, AC-US1-02, AC-US1-03
**Test Plan** (BDD):
- **Given** valid credentials → **When** login → **Then** receive JWT token
Requirements
Must Have AC-IDs in Tasks
CRITICAL: Your tasks.md MUST have AC: fields with AC-IDs for bidirectional linking to work.
AC-ID Format: AC-US{number}-{criteria}
Examples:
AC-US1-01→ Maps toUS-001AC-US2-03→ Maps toUS-002AC-US10-05→ Maps toUS-010
Full Example:
### T-001: Implement User Login
**AC**: AC-US1-01, AC-US1-02, AC-US1-03
**Test Plan** (BDD):
- **Given** valid credentials → **When** login → **Then** receive JWT token
Must Have User Stories in spec.md
Your spec.md must contain user stories with matching IDs:
### US-001: User Authentication
**As a** user
**I want** to log in securely
**So that** I can access my account
**Acceptance Criteria**:
- AC-US1-01: Login with email and password
- AC-US1-02: Receive JWT token on success
- AC-US1-03: Show error on invalid credentials
Supported Heading Formats:
### US-001:(3 hashes) ✅#### US-001:(4 hashes) ✅
Multi-Project Support
Bidirectional linking works automatically with multi-project setups!
Project Detection
SpecWeave detects your project from config or path:
{
"livingDocs": {
"specsDir": ".specweave/docs/internal/specs/backend"
}
}
Detected: projectId = "backend"
Path Adaptation
Links automatically use the correct project folder:
Default Project:
**User Story**: [US-001: Title](../../docs/internal/specs/default/auth-service/us-001-*.md)
Backend Project:
**User Story**: [US-001: Title](../../docs/internal/specs/backend/auth-service/us-001-*.md)
Frontend Project:
**User Story**: [US-001: Title](../../docs/internal/specs/frontend/dashboard/us-001-*.md)
Result: No configuration needed - paths adapt automatically!
Traceability Flow
Before (One-Way Only)
User Story (US-001)
↓
↓ Links to Tasks
↓
Tasks (T-001, T-002, T-003)
✗ No reverse links
After (Bidirectional)
User Story (US-001) ←――――――――――┐
↓ |
↓ Links to Tasks (forward) | Link to User Story (reverse)
↓ |
Tasks (T-001, T-002, T-003) ――┘
Example Navigation
From User Story → See all implementing tasks:
## Implementation
**Increment**: [0031-external-tool-status-sync](../../../../../increments/0031/tasks.md)
**Tasks**:
- [T-001: Create Enhanced Content Builder](../../../../../increments/0031/tasks.md#t-001-create-enhanced-content-builder)
- [T-003: Enhance GitHub Content Sync](../../../../../increments/0031/tasks.md#t-003-enhance-github-content-sync)
- [T-004: Enhance JIRA Content Sync](../../../../../increments/0031/tasks.md#t-004-enhance-jira-content-sync)
From Task → Jump to user story:
### T-001: Create Enhanced Content Builder
**User Story**: [US-001: Rich External Issue Content](../../docs/internal/specs/default/external-tool-status-sync/us-001-rich-external-issue-content.md)
Result: Complete bidirectional navigation!
Benefits
1. Complete Traceability ✅
Navigate from tasks to user stories and back:
- During planning: See which tasks implement which user stories
- During implementation: Jump from task to full user story context
- During review: Verify all acceptance criteria are covered
2. LLM-Friendly ✅
AI assistants (Claude, GitHub Copilot, ChatGPT) can:
- Understand relationships in both directions
- Navigate context automatically
- Provide better suggestions based on user story context
3. Zero Manual Work ✅
- Links created automatically during
/sw:done - No manual linking needed
- Idempotent (safe to run sync multiple times)
4. Multi-Project Aware ✅
- Works with single-project mode (default)
- Works with multi-project mode (backend, frontend, mobile, etc.)
- Paths automatically adapt to project structure
Configuration
Default (No Config Needed)
Bidirectional linking works out of the box if:
- ✅ Living docs sync enabled (
livingDocs.intelligent.enabled: true) - ✅ Tasks have AC: fields with AC-IDs
- ✅ User stories in spec.md match AC-IDs
Optional Disable
To disable bidirectional linking (not recommended):
{
"livingDocs": {
"intelligent": {
"enabled": true,
"bidirectionalLinks": false // ← Disable bidirectional linking
}
}
}
Edge Cases
Tasks Without AC Fields
Scenario: Task doesn't have AC: field
Behavior: Skipped (no mapping, no reverse link)
Example:
### T-001: Setup Infrastructure
**Implementation**: Create Kubernetes cluster...
Result: No bidirectional link added (no AC-IDs to map)
Tasks With Multiple AC-IDs
Scenario: Task has multiple AC-IDs from different user stories
Example:
**AC**: AC-US1-01, AC-US2-03, AC-US3-05
Behavior: Maps to first user story only (US-001)
Reason: One task should have one primary user story
Missing User Story
Scenario: AC-ID references non-existent user story
Example:
**AC**: AC-US99-01 # US-099 doesn't exist
Behavior: Skipped (no matching user story found)
Result: No link added for this task
Duplicate Prevention
Scenario: Run /sw:done twice on same increment
Behavior: Checks if **User Story**: already exists → Skip
Result: Idempotent (safe to run multiple times)
Troubleshooting
"No AC-based task-to-US mapping found"
Problem: Tasks don't have AC: fields
Solution: Add AC-IDs to your tasks:
### T-001: Implement Login
**AC**: AC-US1-01, AC-US1-02 ← Add this!
Links Not Created
Problem: User story IDs don't match AC-IDs
Solution: Ensure consistency:
# In spec.md:
### US-001: User Authentication ← Matches AC-US1-01
# In tasks.md:
**AC**: AC-US1-01, AC-US1-02 ← Must match US-001
Wrong Project Path
Problem: Links point to wrong project folder
Solution: Check livingDocs.specsDir in config:
{
"livingDocs": {
"specsDir": ".specweave/docs/internal/specs/backend" ← Correct project!
}
}
Manual Sync
If automatic sync didn't work during /sw:done:
node -e "import('./dist/src/core/living-docs/spec-distributor.js').then(async ({ SpecDistributor }) => {
const distributor = new SpecDistributor(process.cwd());
await distributor.distribute('0031-external-tool-status-sync');
});"
Output:
🔍 Detecting feature folder for 0031-external-tool-status-sync...
📁 Mapped to external-tool-status-sync (confidence: 90%, method: increment-name)
✅ Written feature overview to external-tool-status-sync/FEATURE.md
✅ Written 7 user stories directly to external-tool-status-sync/
🔗 Added 18 bidirectional links to tasks.md
Technical Implementation
Code Location
src/core/living-docs/spec-distributor.ts
Methods:
updateTasksWithUserStoryLinks()- Adds links to tasks.mdmapTasksToUserStories()- Creates AC-ID based mapping
Pattern Support
Task Headings (both supported):
## T-001:(2 hashes) ✅### T-001:(3 hashes) ✅
User Story Headings (both supported):
### US-001:(3 hashes) ✅#### US-001:(4 hashes) ✅
Algorithm
-
Parse tasks.md:
const taskPattern = /^##+ (T-\d+):.*?$\n[\s\S]*?\*\*AC\*\*:\s*([^\n]+)/gm; -
Extract AC-IDs:
const acPattern = /AC-US(\d+)-\d+/g;
// AC-US1-01 → "1" -
Format US-ID:
const usId = `US-${usNumber.padStart(3, '0')}`;
// "1" → "US-001" -
Find User Story:
const userStory = userStories.find(us => us.id === usId); -
Generate Path:
const relativePath = `../../docs/internal/specs/${projectId}/${featureFolder}/${userStoryFile}`; -
Inject Link:
const link = `**User Story**: [${userStory.id}: ${userStory.title}](${relativePath})`;
Examples
Example 1: Single Task → Single User Story
spec.md:
### US-001: User Login
**As a** user
**I want** to log in with email and password
**So that** I can access my account
**Acceptance Criteria**:
- AC-US1-01: Accept email and password
- AC-US1-02: Validate credentials
- AC-US1-03: Return JWT token
tasks.md (BEFORE):
### T-001: Implement Login Endpoint
**AC**: AC-US1-01, AC-US1-02, AC-US1-03
tasks.md (AFTER):
### T-001: Implement Login Endpoint
**User Story**: [US-001: User Login](../../docs/internal/specs/default/auth-service/us-001-user-login.md)
**AC**: AC-US1-01, AC-US1-02, AC-US1-03
Example 2: Multiple Tasks → Same User Story
spec.md:
### US-002: Password Reset
**As a** user
**I want** to reset my forgotten password
**So that** I can regain access
**Acceptance Criteria**:
- AC-US2-01: Send reset email
- AC-US2-02: Validate reset token
- AC-US2-03: Update password
tasks.md (BEFORE):
### T-002: Implement Reset Email
**AC**: AC-US2-01
### T-003: Implement Token Validation
**AC**: AC-US2-02
### T-004: Implement Password Update
**AC**: AC-US2-03
tasks.md (AFTER):
### T-002: Implement Reset Email
**User Story**: [US-002: Password Reset](../../docs/internal/specs/default/auth-service/us-002-password-reset.md)
**AC**: AC-US2-01
### T-003: Implement Token Validation
**User Story**: [US-002: Password Reset](../../docs/internal/specs/default/auth-service/us-002-password-reset.md)
**AC**: AC-US2-02
### T-004: Implement Password Update
**User Story**: [US-002: Password Reset](../../docs/internal/specs/default/auth-service/us-002-password-reset.md)
**AC**: AC-US2-03
Result: All three tasks link back to the same user story!
FAQ
Q: Do I need to configure anything?
A: No! Bidirectional linking works out of the box if:
- Living docs sync is enabled
- Tasks have AC: fields
- User stories exist in spec.md
Q: Can I disable it?
A: Yes, set livingDocs.intelligent.bidirectionalLinks: false (not recommended)
Q: Does it work with multi-project setups?
A: Yes! Paths automatically adapt to specs/default/, specs/backend/, specs/frontend/, etc.
Q: What if I don't use AC-IDs?
A: No bidirectional links will be created (forward links still work)
Q: Can I run sync multiple times?
A: Yes! It's idempotent (checks if link exists before adding)
Q: Where are the links added?
A: Right after the task heading, before the AC: field
See Also
- Living Docs Sync Guide - Complete living docs architecture
- Test-Aware Planning - AC-ID format explanation
- Multi-Project Setup - Multi-project configuration
Last Updated: 2025-11-13 Status: Production Ready