Skip to main content

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

  1. Create a feature_map.yaml file:
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
  1. Generate documentation:
mouc doc
  1. 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, or outcome)
  • name: Human-readable name
  • description: 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

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 requires OR enables or both
    • The system automatically creates bidirectional edges
  • dependencies: ⚠️ Deprecated - Use requires instead (backward compatible)
  • links: List of links in various formats:
    • design:[DD-123](https://...) - Design doc with markdown link
    • jira:TICKET-123 - Jira ticket reference
    • https://... - Plain URL
  • tags: List of arbitrary tags
  • meta: 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

  1. Keep it current: Update dependencies when architecture changes
  2. Don't over-specify: Only use fields you need
  3. Rich descriptions: Spend time documenting critical capabilities
  4. Consistent tags: Agree on tag conventions with your team
  5. Version control: Keep feature_map.yaml in git
  6. 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

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes with tests
  4. Run linting and tests
  5. Submit a pull request

License

MIT License - see LICENSE file for details

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mouc-0.5.0.tar.gz (196.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mouc-0.5.0-py3-none-any.whl (117.5 kB view details)

Uploaded Python 3

File details

Details for the file mouc-0.5.0.tar.gz.

File metadata

  • Download URL: mouc-0.5.0.tar.gz
  • Upload date:
  • Size: 196.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.8

File hashes

Hashes for mouc-0.5.0.tar.gz
Algorithm Hash digest
SHA256 e65fc8626fbd60322a099975ae74af83c1c5a0b977ca6a341fe1c9de3d37c1ba
MD5 d4f1b5fa5afd0fb4ec80e588cc173114
BLAKE2b-256 5744a7beb999dc0baaf985fc2a1cd556bf06bb842ef4186024a821eb90d57e5f

See more details on using hashes here.

File details

Details for the file mouc-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: mouc-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 117.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.8

File hashes

Hashes for mouc-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 65e34cc119c6d9ef8c2a3103c28faa07d4c8fa01ecdc8802153360ebedb992e3
MD5 72dbf4923ab223c7f5243f3cca9aa27a
BLAKE2b-256 f4f503ebac356eeacc768ba5a1d903e60d94ce42601237dd9a036ecb4dec3a14

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page