A lightweight dependency tracking system for mapping technical capabilities to user stories and outcomes
Project description
Mouc - Mapping Outcomes User stories and Capabilities
A lightweight dependency tracking system for software development that maps relationships between technical capabilities, user stories, and organizational outcomes.
Overview
Mouc helps engineering teams track and visualize dependencies between:
- Capabilities - Technical work your team builds
- User Stories - What other teams need from you
- Outcomes - Business/organizational goals that depend on the work
This is not a project management system. It's a technical dependency tracker that answers "what depends on what" and "what blocks what."
Dependencies can be specified from either direction using requires (what this needs) or enables (what this unblocks), and the system automatically creates bidirectional edges.
Installation
Install with uv (recommended):
uv pip install mouc
Or with pip:
pip install mouc
Quick Start
- Create a
feature_map.yamlfile:
metadata:
version: 1.0
team: middleware_platform
entities:
message_bus:
type: capability
name: Inter-Process Message Bus
description: |
High-performance message passing system for services.
**Key Features:**
- Reliable, ordered message delivery
- Supports both `pub/sub` and *point-to-point* patterns
- See [design doc](https://docs.google.com/document/d/abc) for details
enables: [service_communication] # This unblocks the service communication story
links:
- jira:INFRA-123
tags: [infrastructure]
service_communication:
type: user_story
name: Service Communication
description: Frontend team needs services to communicate
requires: [message_bus] # Or you can specify from this end
meta:
requestor: frontend_team
links:
- jira:STORY-456
q3_launch:
type: outcome
name: Q3 Product Launch
description: Launch new product features in Q3
requires: [service_communication]
links:
- jira:EPIC-789
meta:
target_date: 2024-Q3
- Generate documentation:
mouc doc
- Generate dependency graph:
mouc graph all > deps.dot
dot -Tpng deps.dot -o deps.png
Commands
Documentation Generation
Generate documentation from your feature map:
mouc doc # Markdown to stdout (default)
mouc doc --output docs.md # Markdown to file
mouc doc --format docx --output docs.docx # Microsoft Word format
mouc feature_map.yaml doc # Specify input file
Entity descriptions support markdown formatting (bold, italic, links, lists, code blocks) which is preserved in both markdown and DOCX output.
Gantt Chart Scheduling
Generate Mermaid Gantt charts with resource-aware scheduling:
mouc gantt # Output to stdout
mouc gantt --output schedule.md # Output to markdown file
mouc gantt --start-date 2025-01-01 # Set project start date
mouc gantt --title "Q1 Schedule" # Custom chart title
mouc --config mouc_config.yaml gantt # Use config for resources and settings
Add scheduling metadata to entities in your YAML:
meta:
effort: "2w" # Duration (days, weeks, months)
resources: ["alice", "bob"] # Assigned people/teams
timeframe: "2025q1" # Quarter, week, month, etc.
end_before: "2025-03-31" # Hard deadline
Automatic Resource Assignment
Use wildcards and preferences for flexible resource assignment:
meta:
resources: ["*"] # Assign to any available resource
resources: ["alice|bob|charlie"] # Prefer alice, fall back to bob, then charlie
resources: ["team_a"] # Use group alias from mouc_config.yaml
See docs/gantt.md for Gantt chart features and docs/resources.md for resource management and automatic assignment.
Graph Generation
Generate dependency graphs in DOT format:
# All entities and relationships
mouc graph --view all
# Critical path to a specific outcome
mouc graph --view critical-path --target q3_launch
# Filter by tags
mouc graph --view filtered --tags infrastructure monitoring
# Timeline view grouped by timeframe
mouc graph --view timeline
# Timeframe-colored view (colors indicate time progression)
mouc graph --view timeframe-colored
Render graphs with Graphviz:
mouc graph --view all | dot -Tpng -o graph.png
mouc graph --view all | dot -Tsvg -o graph.svg
YAML Schema
Full Example
metadata:
version: 1.0
last_updated: 2024-01-15
team: middleware
entities:
lock_free_queue:
type: capability
name: Lock-Free Queue Implementation
description: |
High-performance thread-safe queue using atomic operations.
**Performance targets:**
- 10M ops/sec single producer/consumer
- Sub-microsecond latency at p99
Uses *lock-free algorithms* with `std::atomic` for thread safety.
requires: [] # List of entity IDs this depends on
links:
- design:[DD-123](https://docs.google.com/document/d/abc123)
- jira:INFRA-456
tags: [critical, performance] # Arbitrary tags
message_bus:
type: capability
name: Inter-Process Message Bus
description: Reliable message passing built on lock-free queue
requires: [lock_free_queue]
links:
- jira:INFRA-789
tags: [infrastructure]
meta:
timeframe: Q1 2025 # Optional: for timeline view
analytics_realtime:
type: user_story
name: Real-time Analytics Pipeline
description: |
Analytics team needs to process streaming data at 100Hz
with strict latency requirements.
requires: [message_bus] # Can depend on capabilities or other user stories
meta:
requestor: analytics_team # Who asked for this
links:
- jira:STORY-100
tags: [q2_commitment]
mobile_app:
type: outcome
name: Mobile App Launch
description: Launch new mobile application by Q3
requires: [analytics_realtime] # Can depend on user stories or capabilities
links:
- jira:EPIC-1000 # Always present for exec visibility
meta:
target_date: 2024-Q3
tags: [company_priority]
Field Reference
Required fields for all entities:
type: Entity type (capability,user_story, oroutcome)name: Human-readable namedescription: Entity description with markdown formatting support- Inline formatting:
**bold**,*italic*,`code`,[links](url) - Block elements: Lists (ordered/unordered, nested), code blocks (
```) - Formatting is preserved in both markdown and DOCX output
- Inline formatting:
Optional fields for all entities:
requires: List of entity IDs this depends on (what must be completed before this)- Capabilities can only depend on other capabilities
- User stories can depend on capabilities or other user stories
- Outcomes can depend on any entity (capabilities, user stories, or other outcomes)
enables: List of entity IDs that depend on this (what this unblocks)- You can specify edges from either end - use
requiresORenablesor both - The system automatically creates bidirectional edges
- You can specify edges from either end - use
dependencies: ⚠️ Deprecated - Userequiresinstead (backward compatible)links: List of links in various formats:design:[DD-123](https://...)- Design doc with markdown linkjira:TICKET-123- Jira ticket referencehttps://...- Plain URL
tags: List of arbitrary tagsmeta: Dictionary of metadata. Common fields include:timeframe: Time period for timeline view (e.g.,"Q1 2025","Sprint 23")requestor: Team or person requesting (for user stories)target_date: Target completion date (for outcomes)
Specifying Dependencies:
You can specify edges from either direction:
# Option 1: Specify what each entity requires
entities:
cap1:
type: capability
name: Foundation
requires: []
cap2:
type: capability
name: Feature
requires: [cap1] # cap2 depends on cap1
# Option 2: Specify what each entity enables
entities:
cap1:
type: capability
name: Foundation
enables: [cap2] # cap1 unblocks cap2
cap2:
type: capability
name: Feature
requires: []
# Option 3: Mix both (useful for complex graphs)
entities:
cap1:
type: capability
name: Foundation
enables: [cap2, cap3]
cap2:
type: capability
name: Feature A
requires: [cap1]
enables: [story1]
All three examples create the same dependency graph. The system automatically resolves bidirectional edges.
Styling System
Mouc provides a flexible styling system that lets you customize how graphs and markdown output are rendered. You can write Python functions to compute styles based on entity data and graph structure.
Basic Usage
# Import from Python module (must be on PYTHONPATH)
mouc graph --style-module myproject.docs.styling
# Import from file path
mouc graph --style-file ./my_styles.py
# Same for markdown
mouc doc --style-module myproject.docs.styling
mouc doc --style-file ./my_styles.py
Quick Example
# my_styles.py
from mouc.styling import *
@style_node
def timeframe_colors(entity, context):
"""Color entities by their timeframe."""
if 'timeframe' in entity.meta:
timeframes = context.collect_metadata_values('timeframe')
return {
'fill_color': sequential_hue(
entity.meta['timeframe'],
timeframes,
hue_range=(120, 230)
)
}
return {}
@style_node(priority=20)
def highlight_blockers(entity, context):
"""Highlight entities that block company priorities."""
priority_outcomes = [
e for e in context.get_entities_by_type('outcome')
if 'company_priority' in e.tags
]
enabled = context.transitively_enables(entity.id)
for outcome in priority_outcomes:
if outcome.id in enabled:
return {'border_color': '#ff0000', 'border_width': 3}
return {}
@style_label
def custom_labels(entity, context):
"""Show custom labels in markdown output."""
if entity.type == 'capability' and 'critical' in entity.tags:
return '[🔥 Critical Capability]'
return '' # Use default label
See also the full styling documentation.
Use Cases
Find Critical Path
What needs to be done for the Q3 launch?
mouc graph --view critical-path --target q3_launch | dot -Tpng -o critical_path.png
Filter by Team
What infrastructure work is planned?
mouc graph --view filtered --tags infrastructure | dot -Tpng -o infra_work.png
Generate Reports
Create documentation for architecture review:
mouc doc --output architecture_review.md
View Timeline
Group work by time periods (quarters, sprints, etc.):
# Add timeframe metadata to entities:
# meta:
# timeframe: "Q1 2025"
# Clustered by timeframe
mouc graph --view timeline | dot -Tpng -o timeline.png
# Colored by timeframe
mouc graph --view timeframe-colored | dot -Tpng -o timeframe_colored.png
Best Practices
- Keep it current: Update dependencies when architecture changes
- Don't over-specify: Only use fields you need
- Rich descriptions: Spend time documenting critical capabilities
- Consistent tags: Agree on tag conventions with your team
- Version control: Keep feature_map.yaml in git
- Review regularly: Quarterly reviews to prune obsolete items
Development
Setup
# Clone the repository
git clone https://github.com/rnortman/mouc.git
cd mouc
# Install with development dependencies
uv pip install -e ".[dev]"
Testing
# Run tests
pytest
# Run with coverage
pytest --cov=mouc
# Type checking
pyright
# Linting
ruff check src tests
ruff format src tests
Contributing
- Fork the repository
- Create a feature branch
- Make your changes with tests
- Run linting and tests
- Submit a pull request
License
MIT License - see LICENSE file for details
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mouc-0.2.0.tar.gz.
File metadata
- Download URL: mouc-0.2.0.tar.gz
- Upload date:
- Size: 163.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d63daab5de6079273862135486b4f6d4050cb267e8f18b439727ef8660ce6ce3
|
|
| MD5 |
1ea5401ad2617ca6b620cd77e8c76fa9
|
|
| BLAKE2b-256 |
48fe6c531f217c4fec21b2ef9ffcac4772d8d91502c5b05d0eae39db7f638709
|
File details
Details for the file mouc-0.2.0-py3-none-any.whl.
File metadata
- Download URL: mouc-0.2.0-py3-none-any.whl
- Upload date:
- Size: 94.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d469c84cd15535b2c6bffccb18e1965cf2f02d73d01e39032961d906abd1d414
|
|
| MD5 |
ec6177fea66b4535f9fa72bb6613ec3f
|
|
| BLAKE2b-256 |
2d0473b30544ace44cd44a595411b843999f47e96e440ffd78253cd6406827fe
|