# Commit Classification Verification - Duetto Contractor Repos

**Date:** 2026-02-26
**Config:** `/Users/masa/Duetto/repos/gitflow-contractors.yaml`
**Analysis window:** 2 weeks
**Total commits processed:** 689

---

## Summary

Commit classification is **working correctly** for the primary outputs (untracked_commits CSV,
weekly_categorization CSV). However, two bugs were discovered:

1. **`developer_weekly_trends` CSV shows 100% "other"** - the WeeklyTrendsWriter does not call
   `categorize_commit()`; it relies on a `category` field that is never set on commits loaded
   from the database.
2. **`show_analysis_summary()` crashes** with `TypeError: unexpected keyword argument 'total_commits'`
   due to a mismatch between caller keyword args and method parameter names. The analysis completes
   successfully but the final summary display is skipped.

---

## Classification Results (Correct Reports)

### `untracked_commits_20260225.csv` - 162 commits

Category distribution:

| Category       | Count | Pct   |
|----------------|-------|-------|
| feature        |  34   | 21.0% |
| bug_fix        |  31   | 19.1% |
| other          |  28   | 17.3% |
| chore          |  12   |  7.4% |
| test           |  10   |  6.2% |
| maintenance    |   9   |  5.6% |
| infrastructure |   7   |  4.3% |
| documentation  |   6   |  3.7% |
| wip            |   4   |  2.5% |
| configuration  |   4   |  2.5% |
| style          |   3   |  1.9% |
| content        |   3   |  1.9% |
| refactor       |   2   |  1.2% |
| build          |   2   |  1.2% |
| deployment     |   2   |  1.2% |
| ui             |   2   |  1.2% |
| version        |   2   |  1.2% |
| performance    |   1   |  0.6% |

The distribution is **reasonable and not dominated by "other"** (17.3%). The top categories
(feature, bug_fix) reflect active sprint work.

### `weekly_categorization_20260225.csv` - Week 2026-02-16 (136 commits)

| Category       | Count | Pct   |
|----------------|-------|-------|
| bug_fix        |  33   | 24.3% |
| feature        |  32   | 23.5% |
| other          |  21   | 15.4% |
| chore          |  10   |  7.4% |
| infrastructure |  10   |  7.4% |
| maintenance    |   4   |  2.9% |
| wip            |   4   |  2.9% |
| documentation  |   3   |  2.2% |
| refactor       |   2   |  1.5% |
| style          |   2   |  1.5% |
| test           |   2   |  1.5% |
| ui             |   2   |  1.5% |
| version        |   2   |  1.5% |
| build          |   2   |  1.5% |
| configuration  |   2   |  1.5% |
| content        |   2   |  1.5% |
| deployment     |   2   |  1.5% |
| performance    |   1   |  0.7% |

---

## Verification: Correct Classifications

### Conventional Commit Prefixes - All Correct

No mismatches found between `fix:` / `feat:` / `chore:` / `refactor:` prefix patterns
and the assigned category. Example correct classifications:

```
fix: package.json to reduce vulnerabilities        -> bug_fix  (correct, fix: prefix)
lint                                               -> chore    (correct, lint keyword)
chore: move api response type                      -> chore    (correct, chore: prefix)
Add CoreDNS and Fargate configurations for EKS     -> feature  (correct, "Add" action)
DE-2295 add de log lib in data_export folder       -> feature  (correct, "add" action)
```

### Multi-Keyword Commits - Correct

```
IC-3182: Delphi Evaluate Booking Error Handling    -> bug_fix   (correct, "Error")
PLG-276: Fix Unicorn selectors, remove Sub Menus   -> bug_fix   (correct, "Fix")
XP-3713-Simplified-Pricing-React-Code              -> refactor  (correct, "Simplified" -> simplify)
```

---

## Classification Quality Issues Found

### 1. Over-broad "documentation" pattern - FALSE POSITIVES

The `\b(comment|comments)\b` pattern in `documentation` category matches commit messages
referring to *code review comments*, not documentation.

**Misclassified as documentation:**
```
"XP-3698 Code review comments resolved"     -> documentation (should be: refactor/chore)
"review comments resolved"                   -> documentation (should be: refactor/chore)
"XP-3687 - Comments Resolved"               -> documentation (should be: refactor/chore)
"IC-3015 | Changes for ... Comments in..."  -> documentation (should be: feature/refactor)
```

**Impact:** 5/6 documentation commits are false positives (83% FP rate for documentation).

**Fix:** Add a negative lookahead to exclude "code review" + "comments resolved" patterns.
Or reorder to check `refactor` before `documentation` for messages with "resolved".

### 2. "infrastructure" category misclassifies frontend/UI work

The `\b(logging|metrics)\b` pattern hits on non-infra commits:

```
"Revert 'BI-5516 Y-axis title auto-derive from metrics'"  -> infrastructure
"BI-5516 Y-axis title auto-derive from metrics"           -> infrastructure
"PLG-276: Remove legacy header components..."             -> infrastructure (via "legacy" -> legacy)
"IC-2386 Integ Services Logging Changes for Delphi"       -> infrastructure (correct)
```

Frontend "metrics" (chart axes) is being conflated with infrastructure monitoring metrics.

**Impact:** ~3/7 infrastructure commits are likely misclassified (43% FP rate).

**Fix:** Add negative context for frontend: `\b(y-axis|chart|dashboard)\b.*\bmetrics\b`

### 3. WIP catches non-WIP tickets due to "story updates"

```
"UIARCH-3040: ContentHeader datePicker as ReactNode, story updates, Storybook fixes"
  -> wip (misclassified; "story" in "Storybook" matched wip pattern)
```

**Fix:** Make the `story` pattern in wip more specific (e.g. `\bstory book\b` not `\bstory\b`).

### 4. "other" commits (28, 17.3%) - Notable unclassifiable messages

Many short/cryptic commit messages fall through to "other":
```
"equalization"               - single word, ambiguous
"keep postgres to 14"        - maintenance/config but no keywords
"fmt"                        - style/chore but "fmt" not in patterns
"keep irving"                - environment config, no keywords
"created-by"                 - tag/label, no keywords
"maintained-by = data-eng"   - IaC tag, no keywords
"departament to data platform" - typo, no keywords
```

These are legitimately hard to classify; 17% "other" is acceptable for a rule-based system
handling diverse commit message styles.

---

## Bug 1: `developer_weekly_trends` - ALL commits classified as "other"

**File:** `src/gitflow_analytics/reports/weekly_trends_writer.py`
**Method:** `_get_commit_classification()`

**Root cause:** `_commit_to_dict()` in `cache.py` (line 952) does not include a `category`
field. The `CachedCommit` SQLAlchemy model also has no `category` column. When commits are
loaded from the database and passed to `WeeklyTrendsWriter`, every commit lacks `category`,
`predicted_class`, and `classification` fields - so `_get_commit_classification()` always
returns `"other"`.

**Proof:**
- `developer_weekly_trends_20260225.csv`: 297 total commits, 0 feature, 0 bug_fix, 297 other
- `weekly_categorization_20260225.csv`: 136 commits, 32 feature (23.5%), 33 bug_fix (24.3%)
  - This works because `csv_writer.py` calls `ticket_extractor.categorize_commit()` on each
    commit message at write time

**Additional issue:** `classification_categories` in `WeeklyTrendsWriter.__init__` lists only
9 categories `[feature, bug_fix, refactor, documentation, maintenance, test, style, build, other]`
but `categorize_commit()` now returns 18+ categories including `chore`, `infrastructure`,
`configuration`, `wip`, `version`, `ui`, `content`, `deployment`, `performance`, `integration`,
`security`. Any commit with an extended category would show `total_commits > sum(category_counts)`.

**Fix required:**
Option A (recommended): Pass `ticket_extractor` to `generate_weekly_trends_reports()` and call
`categorize_commit()` inside `_get_commit_classification()`.

Option B: Pre-populate `category` on all commits in `all_commits` list in `cli.py` before
passing to `WeeklyTrendsWriter`, using `analyzer.ticket_extractor.categorize_commit()`.

Also fix: Expand `classification_categories` to include all categories returned by
`categorize_commit()`, or use dynamic category discovery.

**Location:**
- `src/gitflow_analytics/reports/weekly_trends_writer.py` lines 28-38 (categories list)
- `src/gitflow_analytics/reports/weekly_trends_writer.py` lines 367-398 (_get_commit_classification)
- `src/gitflow_analytics/cli.py` lines 3888-3895 (call site)

---

## Bug 2: `show_analysis_summary()` TypeError on completion

**Error:** `RichProgressDisplay.show_analysis_summary() got an unexpected keyword argument 'total_commits'`

**Location:** `src/gitflow_analytics/cli.py` line 4351

**Caller (cli.py line 4351):**
```python
display.show_analysis_summary(
    total_commits=len(all_commits),
    total_prs=len(all_prs),
    active_developers=len(developer_stats),
    ticket_coverage=ticket_analysis["commit_coverage_pct"],
    story_points=total_story_points,
    qualitative_analyzed=qualitative_count,
)
```

**Actual signature (progress_display.py line 1034):**
```python
def show_analysis_summary(self, commits, developers, tickets, prs=None, untracked=None):
```

The caller uses keyword args that don't match the method's positional parameter names.
The analysis runs to completion (689 commits, all reports written) but the final display
summary is skipped with an error.

**Fix:** Either update the caller in `cli.py` to use positional args matching the method
signature, or update the method signature to accept the keyword args used by the caller.

---

## Repositories Analyzed

| Repository      | Status  | Commits |
|-----------------|---------|---------|
| datapipelines   | Success |         |
| integrations    | Success |         |
| customer-domain | Success |         |
| duetto-frontend | Success |         |
| intelligence-domain | Success |     |
| ops             | Success |         |
| ops-tf          | Success |         |
| duetto-infra    | Success | 83      |

**Total:** 689 commits analyzed, 63 batches classified.

---

## Actionable Recommendations

1. **HIGH - Fix developer_weekly_trends (Bug 1):** This report is completely broken. All 297
   developer-week rows show 0 for every classification except "other". Cannot be used for
   developer classification trend analysis until fixed.

2. **HIGH - Fix show_analysis_summary (Bug 2):** The final summary display always crashes.
   Non-blocking (reports are still written) but misleads users into thinking the run failed.

3. **MEDIUM - Expand classification_categories in WeeklyTrendsWriter:** The 9-category list
   is stale. Add chore, infrastructure, configuration, wip, version, ui, content, deployment,
   performance, integration, security to match the full set from categorize_commit().

4. **LOW - Fix "documentation" false positives:** "code review comments resolved" should not
   be classified as documentation. Add negative pattern for "comments resolved" / "review".

5. **LOW - Fix "infrastructure" false positives:** Frontend "metrics" (chart Y-axis) should
   not match the infrastructure monitoring pattern.
