Analyse the portfolio activity data to identify cross-team contributors, unmatched activity, and load distribution across repos and people. Reach for this skill when a supervisor wants to understand who is contributing where across the team's repos, or when the portfolio output shows unexpected activity patterns.
Installs into .claude/skills of the current project.
Are you the author of Cross Team Contributor Analysis?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/mcorbett51090-cross-team-contributor-analysis)
---
name: cross-team-contributor-analysis
description: "Analyse the portfolio activity data to identify cross-team contributors, unmatched activity, and load distribution across repos and people. Reach for this skill when a supervisor wants to understand who is contributing where across the team's repos, or when the portfolio output shows unexpected activity patterns."
---
# Skill: Cross-Team Contributor Analysis
The portfolio collection script captures activity by person and by repo. This skill structures the analysis pass over that data to answer the supervisor's question: "who is contributing where, and is the distribution what I expect?"
## When to reach for this skill
- A supervisor asks "who has been touching the API repo this week?" or "why does Alex have so many PRs this cycle?"
- The `activity-rollup.md` shows a contributor with unexpectedly high or low counts.
- A project is marked "active" in the cross-repo filter but the activity counts suggest otherwise.
- A new team member joined and the supervisor wants to verify their activity is being captured correctly.
## Step 1 — Load the activity JSON
The analysis starts from `portfolio-activity.json` (generated by `scripts/portfolio-collect.py`). The key top-level keys are:
```json
{
"generated_at": "...",
"collection_window_days": 7,
"repos": { "<owner/repo>": { "commits": [...], "prs": [...], "issues": [...] } },
"team": { "<login>": { "name": "...", "role": "..." } },
"unmatched_activity": { ... }
}
```
## Step 2 — Build the contributor × repo matrix
Produce a count of activity (commits + PRs + issues opened) per contributor per repo for the collection window:
```
Contributor × Repo matrix:
| Contributor | repo-A | repo-B | repo-C | Total | Notes |
|---|---|---|---|---|---|
| Alice (login) | 12 | 3 | 0 | 15 | Backend-heavy |
| Bob (login) | 0 | 8 | 5 | 13 | Infra + docs |
| Unmatched | 2 | 0 | 1 | 3 | See Step 4 |
```
Flags to surface:
- A contributor with zero activity across all repos for a week is worth noting (on leave? blocked? missing from config?).
- A contributor with very high activity in a single repo and zero in others may indicate silo risk.
## Step 3 — Identify load imbalance patterns
Compare each contributor's total against the team average. Surface:
- **Over-loaded contributors** — consistently above average across multiple windows
- **Under-loaded contributors** — zero or near-zero activity over multiple windows (not just one week)
- **Repo concentration** — one repo receiving a disproportionate share of the team's attention
**Do not present these as performance evaluations.** Activity counts are a signal for a conversation, not a verdict. Document the framing explicitly in the report: "These counts represent observable GitHub activity. They do not capture meetings, design work, reviews in other tools, or blocked time."
## Step 4 — Resolve unmatched activity
`unmatched_activity` in the JSON contains events that matched no project filter and no team-login entry. Two causes:
1. **Login not in `team-portfolio.json`** — a contributor whose `login` field is not in the `team` config. Add them to the config.
2. **Activity from a bot or CI account** — GitHub Actions, Dependabot, or a deploy bot. These should be noted as non-human contributors in the config with `role: bot`.
Surface unmatched counts with a note: "N activity events unmatched — see team-portfolio.json `team` section for missing logins."
## Step 5 — Produce the analysis summary
```
Period: [start] to [end] ([N] days)
Team members analysed: [N]
Repos: [N]
Top contributors by total activity:
1. [Name] — [N] events across [repos]
2. [Name] — [N] events across [repos]
Concentration flags:
[Contributor] — [N]% of their activity in [repo] (silo signal — worth checking in)
[Repo] — [N]% of all team activity (possible bottleneck or sprint focus)
Zero-activity team members this window:
[Name] — [check on-leave / blocked / config issue]
Unmatched activity: [N] events — [N] distinct logins — add to team config if human contributors
Notes: Activity counts are observable GitHub events, not a productivity measure. Discuss patterns in 1:1s, not in the report itself.
```
## Pitfalls
- Presenting GitHub activity counts as a performance metric — they are an activity signal; the supervisor uses them to start a conversation, not close one.
- Treating a zero-activity week as a performance problem without checking PTO, sick leave, or blocked status.
- Forgetting that unmatched activity may represent important work — a contractor, a part-time contributor, or a CI bot can distort the unmatched count.
- Comparing counts across repos with very different activity norms (a documentation repo vs. an active API repo) without normalizing the context.
## See also
- [`../../CLAUDE.md`](../../CLAUDE.md) — §5 anti-pattern: "unmatched activity is signal, not an error"
- [`../../skills/portfolio-setup/SKILL.md`](../../skills/portfolio-setup/SKILL.md) — configuring the team login list that this skill reads
- [`../../skills/cross-repo-project-tracking/SKILL.md`](../../skills/cross-repo-project-tracking/SKILL.md) — project-attributed analysis; this skill covers the unattributed remainder