Skip to content

ownership

Full name: tenets.core.examiner.ownership

ownership

Code ownership tracking module for examination.

This module analyzes code ownership patterns by examining git history, identifying primary contributors, tracking knowledge distribution, and detecting bus factor risks. It helps understand team dynamics and knowledge silos within a codebase.

The ownership tracker integrates with git to provide insights into who knows what parts of the code and where knowledge gaps might exist.

Classes

ContributorInfodataclass

Python
ContributorInfo(name: str, email: str, total_commits: int = 0, total_lines_added: int = 0, total_lines_removed: int = 0, files_touched: Set[str] = set(), files_created: Set[str] = set(), primary_languages: Dict[str, int] = dict(), expertise_areas: List[str] = list(), first_commit_date: Optional[datetime] = None, last_commit_date: Optional[datetime] = None, active_days: int = 0, commit_frequency: float = 0.0, review_participation: int = 0, collaboration_score: float = 0.0, bus_factor_risk: float = 0.0, knowledge_domains: Set[str] = set())

Information about a code contributor.

Tracks detailed statistics and patterns for individual contributors including their areas of expertise, contribution patterns, and impact.

ATTRIBUTEDESCRIPTION
name

Contributor name

TYPE:str

email

Contributor email

TYPE:str

total_commits

Total number of commits

TYPE:int

total_lines_added

Total lines added

TYPE:int

total_lines_removed

Total lines removed

TYPE:int

files_touched

Set of files modified

TYPE:Set[str]

files_created

Set of files created

TYPE:Set[str]

primary_languages

Languages most frequently used

TYPE:Dict[str, int]

expertise_areas

Areas of codebase expertise

TYPE:List[str]

first_commit_date

Date of first contribution

TYPE:Optional[datetime]

last_commit_date

Date of most recent contribution

TYPE:Optional[datetime]

active_days

Number of days with commits

TYPE:int

commit_frequency

Average commits per active day

TYPE:float

review_participation

Number of reviews participated in

TYPE:int

collaboration_score

Score indicating collaboration level

TYPE:float

bus_factor_risk

Risk score for bus factor

TYPE:float

knowledge_domains

Specific knowledge domains

TYPE:Set[str]

Attributes
net_lines_contributedproperty
Python
net_lines_contributed: int

Calculate net lines contributed.

RETURNSDESCRIPTION
int

Lines added minus lines removed

TYPE:int

productivity_scoreproperty
Python
productivity_score: float

Calculate productivity score.

Combines various metrics to assess productivity.

RETURNSDESCRIPTION
float

Productivity score (0-100)

TYPE:float

is_activeproperty
Python
is_active: bool

Check if contributor is currently active.

Considers a contributor active if they've committed in last 30 days.

RETURNSDESCRIPTION
bool

True if active

TYPE:bool

expertise_levelproperty
Python
expertise_level: str

Determine expertise level.

RETURNSDESCRIPTION
str

Expertise level (expert, senior, intermediate, junior)

TYPE:str

FileOwnershipdataclass

Python
FileOwnership(path: str, primary_owner: Optional[str] = None, ownership_percentage: float = 0.0, contributors: List[Tuple[str, int]] = list(), total_changes: int = 0, last_modified: Optional[datetime] = None, last_modified_by: Optional[str] = None, creation_date: Optional[datetime] = None, created_by: Optional[str] = None, complexity: Optional[float] = None, is_orphaned: bool = False, knowledge_concentration: float = 0.0, change_frequency: float = 0.0)

Ownership information for a single file.

Tracks who owns and maintains specific files, including primary owners, contributors, and change patterns.

ATTRIBUTEDESCRIPTION
path

File path

TYPE:str

primary_owner

Main contributor to the file

TYPE:Optional[str]

ownership_percentage

Primary owner's contribution percentage

TYPE:float

contributors

List of all contributors

TYPE:List[Tuple[str, int]]

total_changes

Total number of changes

TYPE:int

last_modified

Last modification date

TYPE:Optional[datetime]

last_modified_by

Last person to modify

TYPE:Optional[str]

creation_date

File creation date

TYPE:Optional[datetime]

created_by

Original creator

TYPE:Optional[str]

complexity

File complexity if available

TYPE:Optional[float]

is_orphaned

Whether file lacks active maintainer

TYPE:bool

knowledge_concentration

How concentrated knowledge is

TYPE:float

change_frequency

How often file changes

TYPE:float

Attributes
contributor_countproperty
Python
contributor_count: int

Get number of unique contributors.

RETURNSDESCRIPTION
int

Unique contributor count

TYPE:int

bus_factorproperty
Python
bus_factor: int

Calculate bus factor for this file.

Number of people who need to be unavailable before knowledge is lost.

RETURNSDESCRIPTION
int

Bus factor (1 is high risk)

TYPE:int

risk_levelproperty
Python
risk_level: str

Determine ownership risk level.

RETURNSDESCRIPTION
str

Risk level (critical, high, medium, low)

TYPE:str

TeamOwnershipdataclass

Python
TeamOwnership(teams: Dict[str, List[str]] = dict(), team_territories: Dict[str, List[str]] = dict(), cross_team_files: List[str] = list(), collaboration_matrix: Dict[Tuple[str, str], int] = dict(), team_expertise: Dict[str, Set[str]] = dict(), team_bus_factor: Dict[str, int] = dict())

Team-level ownership patterns.

Aggregates ownership information across teams or groups, identifying collaboration patterns and knowledge distribution.

ATTRIBUTEDESCRIPTION
teams

Dictionary of team members

TYPE:Dict[str, List[str]]

team_territories

Areas owned by each team

TYPE:Dict[str, List[str]]

cross_team_files

Files touched by multiple teams

TYPE:List[str]

collaboration_matrix

Team collaboration frequencies

TYPE:Dict[Tuple[str, str], int]

team_expertise

Expertise areas by team

TYPE:Dict[str, Set[str]]

team_bus_factor

Bus factor by team

TYPE:Dict[str, int]

OwnershipReportdataclass

Python
OwnershipReport(total_contributors: int = 0, total_files_analyzed: int = 0, active_contributors: int = 0, contributors: List[ContributorInfo] = list(), file_ownership: Dict[str, FileOwnership] = dict(), orphaned_files: List[str] = list(), high_risk_files: List[Dict[str, Any]] = list(), knowledge_silos: List[Dict[str, Any]] = list(), bus_factor: int = 0, team_ownership: Optional[TeamOwnership] = None, ownership_distribution: Dict[str, float] = dict(), collaboration_graph: Dict[Tuple[str, str], int] = dict(), expertise_map: Dict[str, List[str]] = dict(), recommendations: List[str] = list(), risk_score: float = 0.0)

Comprehensive code ownership analysis report.

Provides detailed insights into code ownership patterns, knowledge distribution, bus factor risks, and team dynamics.

ATTRIBUTEDESCRIPTION
total_contributors

Total number of contributors

TYPE:int

active_contributors

Currently active contributors

TYPE:int

contributors

List of contributor information

TYPE:List[ContributorInfo]

file_ownership

Ownership by file

TYPE:Dict[str, FileOwnership]

orphaned_files

Files without active maintainers

TYPE:List[str]

high_risk_files

Files with bus factor risks

TYPE:List[Dict[str, Any]]

knowledge_silos

Areas with concentrated knowledge

TYPE:List[Dict[str, Any]]

bus_factor

Overall project bus factor

TYPE:int

team_ownership

Team-level ownership patterns

TYPE:Optional[TeamOwnership]

ownership_distribution

Distribution of ownership

TYPE:Dict[str, float]

collaboration_graph

Collaboration relationships

TYPE:Dict[Tuple[str, str], int]

expertise_map

Map of expertise areas

TYPE:Dict[str, List[str]]

recommendations

Actionable recommendations

TYPE:List[str]

risk_score

Overall ownership risk score

TYPE:float

Attributes
health_scoreproperty
Python
health_score: float

Calculate ownership health score.

Higher scores indicate better knowledge distribution.

RETURNSDESCRIPTION
float

Health score (0-100)

TYPE:float

Functions
to_dict
Python
to_dict() -> Dict[str, Any]

Convert report to dictionary.

RETURNSDESCRIPTION
Dict[str, Any]

Dict[str, Any]: Dictionary representation

Source code in tenets/core/examiner/ownership.py
Python
def to_dict(self) -> Dict[str, Any]:
    """Convert report to dictionary.

    Returns:
        Dict[str, Any]: Dictionary representation
    """
    data = {
        "total_contributors": self.total_contributors,
        "total_files_analyzed": self.total_files_analyzed,
        "active_contributors": self.active_contributors,
        "bus_factor": self.bus_factor,
        "orphaned_files": len(self.orphaned_files),
        "high_risk_files": len(self.high_risk_files),
        "knowledge_silos": len(self.knowledge_silos),
        "risk_score": round(self.risk_score, 2),
        "top_contributors": [
            {
                "name": c.name,
                "commits": c.total_commits,
                "files": len(c.files_touched),
                "expertise": c.expertise_level,
            }
            for c in sorted(self.contributors, key=lambda x: x.total_commits, reverse=True)[:10]
        ],
        "ownership_distribution": self.ownership_distribution,
        "recommendations": self.recommendations,
    }
    # Some tests expect total_files_analyzed when no repo
    if not data.get("total_files_analyzed") and hasattr(self, "total_files_analyzed"):
        try:
            data["total_files_analyzed"] = int(self.total_files_analyzed)
        except Exception:
            pass
    return data

OwnershipTracker

Python
OwnershipTracker(config: TenetsConfig)

Tracker for code ownership patterns.

Analyzes git history to understand code ownership, knowledge distribution, and collaboration patterns within a codebase.

ATTRIBUTEDESCRIPTION
config

Configuration object

logger

Logger instance

git_analyzer

Git analyzer instance

TYPE:Optional[GitAnalyzer]

Initialize ownership tracker.

PARAMETERDESCRIPTION
config

TenetsConfig instance

TYPE:TenetsConfig

Source code in tenets/core/examiner/ownership.py
Python
def __init__(self, config: TenetsConfig):
    """Initialize ownership tracker.

    Args:
        config: TenetsConfig instance
    """
    self.config = config
    self.logger = get_logger(__name__)
    self.git_analyzer: Optional[GitAnalyzer] = None
Functions
track
Python
track(repo_path: Path, since_days: int = 365, include_tests: bool = True, team_mapping: Optional[Dict[str, List[str]]] = None) -> OwnershipReport

Track code ownership for a repository.

Analyzes git history to determine ownership patterns, identify risks, and provide insights into knowledge distribution.

PARAMETERDESCRIPTION
repo_path

Path to git repository

TYPE:Path

since_days

Days of history to analyze

TYPE:intDEFAULT:365

include_tests

Whether to include test files

TYPE:boolDEFAULT:True

team_mapping

Optional mapping of team names to members

TYPE:Optional[Dict[str, List[str]]]DEFAULT:None

RETURNSDESCRIPTION
OwnershipReport

Comprehensive ownership analysis

TYPE:OwnershipReport

Example

tracker = OwnershipTracker(config) report = tracker.track(Path("."), since_days=90) print(f"Bus factor: {report.bus_factor}")

Source code in tenets/core/examiner/ownership.py
Python
def track(
    self,
    repo_path: Path,
    since_days: int = 365,
    include_tests: bool = True,
    team_mapping: Optional[Dict[str, List[str]]] = None,
) -> OwnershipReport:
    """Track code ownership for a repository.

    Analyzes git history to determine ownership patterns, identify
    risks, and provide insights into knowledge distribution.

    Args:
        repo_path: Path to git repository
        since_days: Days of history to analyze
        include_tests: Whether to include test files
        team_mapping: Optional mapping of team names to members

    Returns:
        OwnershipReport: Comprehensive ownership analysis

    Example:
        >>> tracker = OwnershipTracker(config)
        >>> report = tracker.track(Path("."), since_days=90)
        >>> print(f"Bus factor: {report.bus_factor}")
    """
    self.logger.debug(f"Tracking ownership for {repo_path}")

    # Initialize git analyzer
    self.git_analyzer = GitAnalyzer(repo_path)

    if not self.git_analyzer.is_repo():
        self.logger.warning(f"Not a git repository: {repo_path}")
        return OwnershipReport()

    report = OwnershipReport()

    # Analyze contributors
    self._analyze_contributors(report, since_days)

    # Analyze file ownership
    self._analyze_file_ownership(report, include_tests)

    # Identify risks
    self._identify_ownership_risks(report)

    # Analyze team patterns if mapping provided
    if team_mapping:
        self._analyze_team_ownership(report, team_mapping)

    # Calculate collaboration patterns
    self._calculate_collaboration_patterns(report)

    # Generate expertise map
    self._generate_expertise_map(report)

    # Calculate overall metrics
    self._calculate_overall_metrics(report)

    # Generate recommendations
    report.recommendations = self._generate_recommendations(report)

    self.logger.debug(
        f"Ownership tracking complete: {report.total_contributors} contributors, "
        f"bus factor: {report.bus_factor}"
    )

    return report
analyze_ownership
Python
analyze_ownership(repo_path: Path, **kwargs: Any) -> OwnershipReport

Analyze ownership for a repository path.

This is an alias for the track() method to maintain backward compatibility.

PARAMETERDESCRIPTION
repo_path

Path to repository

TYPE:Path

**kwargs

Additional arguments passed to track()

TYPE:AnyDEFAULT:{}

RETURNSDESCRIPTION
OwnershipReport

Comprehensive ownership analysis

TYPE:OwnershipReport

Source code in tenets/core/examiner/ownership.py
Python
def analyze_ownership(self, repo_path: Path, **kwargs: Any) -> OwnershipReport:
    """Analyze ownership for a repository path.

    This is an alias for the track() method to maintain backward compatibility.

    Args:
        repo_path: Path to repository
        **kwargs: Additional arguments passed to track()

    Returns:
        OwnershipReport: Comprehensive ownership analysis
    """
    return self.track(repo_path, **kwargs)

Functions

track_ownership

Python
track_ownership(repo_path: Path, since_days: int = 90, include_tests: bool = True, team_mapping: Optional[Dict[str, List[str]]] = None, config: Optional[TenetsConfig] = None) -> OwnershipReport

Track code ownership for a repository path.

A convenient functional API that uses OwnershipTracker under the hood.

PARAMETERDESCRIPTION
repo_path

Path to repository

TYPE:Path

since_days

How many days of history to analyze

TYPE:intDEFAULT:90

include_tests

Whether to include test files in analysis

TYPE:boolDEFAULT:True

team_mapping

Optional mapping of team names to member emails

TYPE:Optional[Dict[str, List[str]]]DEFAULT:None

config

Optional TenetsConfig

TYPE:Optional[TenetsConfig]DEFAULT:None

RETURNSDESCRIPTION
OwnershipReport

Comprehensive ownership analysis

TYPE:OwnershipReport

Source code in tenets/core/examiner/ownership.py
Python
def track_ownership(
    repo_path: Path,
    since_days: int = 90,
    include_tests: bool = True,
    team_mapping: Optional[Dict[str, List[str]]] = None,
    config: Optional[TenetsConfig] = None,
) -> OwnershipReport:
    """Track code ownership for a repository path.

    A convenient functional API that uses OwnershipTracker under the hood.

    Args:
        repo_path: Path to repository
        since_days: How many days of history to analyze
        include_tests: Whether to include test files in analysis
        team_mapping: Optional mapping of team names to member emails
        config: Optional TenetsConfig

    Returns:
        OwnershipReport: Comprehensive ownership analysis
    """
    tracker = OwnershipTracker(config or TenetsConfig())
    return tracker.track(
        repo_path=repo_path,
        since_days=since_days,
        include_tests=include_tests,
        team_mapping=team_mapping,
    )