# Sprint Plan: Quality Suite Hardening

## Summary

Transform quality tests from threshold-based (`max_allowed = N`) to baseline-based enforcement, fix detection holes, and add self-tests.

## Execution Checklist

### Phase 1: Foundation Infrastructure

- [ ] Create `tests/quality/_baseline.py` with `Violation`, `assert_no_new_violations()`, `content_hash()`
- [ ] Create `tests/quality/_helpers.py` with centralized `find_source_files()`, `parse_file_safe()`
- [ ] Create `tests/quality/baselines.json` (empty initially, schema v1)
- [ ] Create `tests/quality/test_baseline_self.py` with infrastructure self-tests

### Phase 2: Fix Detection Holes

- [ ] Fix `test_no_ignored_tests_without_reason`: Add missing `skipif_pattern` variable and usage
- [ ] Fix `test_no_hardcoded_paths`: Replace `line.split(pattern)` with `match.start()` comparison
- [ ] Replace all `except SyntaxError: continue` with `parse_file_safe()` + error collection
- [ ] Add self-tests for each fixed detector

### Phase 3: Migrate to Baseline Enforcement

Priority order (highest gaming risk):

1. [ ] `test_no_stale_todos` (cap: 10)
2. [ ] `test_no_trivial_wrapper_functions` (cap: 42)
3. [ ] `test_no_high_complexity_functions` (cap: 2)
4. [ ] `test_no_long_parameter_lists` (cap: 35)
5. [ ] `test_no_repeated_code_patterns` (cap: 177)
6. [ ] `test_no_god_classes` (cap: 1)
7. [ ] `test_no_deep_nesting` (cap: 2)
8. [ ] `test_no_long_methods` (cap: 7)
9. [ ] `test_no_feature_envy` (cap: 5)
10. [ ] `test_no_orphaned_imports` (cap: 5)
11. [ ] `test_no_deprecated_patterns` (cap: 5)
12. [ ] `test_no_assertion_roulette` (cap: 50)
13. [ ] `test_no_conditional_test_logic` (cap: 40)
14. [ ] `test_no_sleepy_tests` (cap: 3)
15. [ ] `test_no_unknown_tests` (cap: 5)
16. [ ] `test_no_redundant_prints` (cap: 5)
17. [ ] `test_no_exception_handling_in_tests` (cap: 3)
18. [ ] `test_no_magic_numbers_in_assertions` (cap: 50)
19. [ ] `test_no_sensitive_equality` (cap: 10)
20. [ ] `test_no_eager_tests` (cap: 10)
21. [ ] `test_no_duplicate_test_names` (cap: 15)
22. [ ] `test_no_long_test_methods` (cap: 3)
23. [ ] `test_fixtures_have_type_hints` (cap: 10)
24. [ ] `test_no_unused_fixture_parameters` (cap: 5)
25. [ ] `test_fixture_scope_appropriate` (cap: 5)
26. [ ] `test_no_pytest_raises_without_match` (cap: 50)
27. [ ] `test_no_magic_numbers` (cap: 10)
28. [ ] `test_no_repeated_string_literals` (cap: 30)
29. [ ] `test_no_alias_imports` (cap: 10)
30. [ ] `test_no_redundant_type_aliases` (cap: 2)
31. [ ] `test_no_passthrough_classes` (cap: 1)
32. [ ] `test_no_duplicate_function_bodies` (cap: 1)
33. [ ] `test_helpers_not_scattered` (cap: 15)
34. [ ] `test_no_duplicate_helper_implementations` (cap: 25)
35. [ ] `test_module_size_limits` (soft cap: 5, hard: 0)

### Phase 4: Generate Initial Baseline

- [ ] Run all quality tests to collect current violations
- [ ] Generate `baselines.json` with frozen violation IDs
- [ ] Verify all tests pass with baseline enforcement
- [ ] Remove `max_allowed` assertions from all tests

### Phase 5: Advanced Improvements (Optional)

- [ ] Replace magic value allowlists with "must be named" rule
- [ ] Add `.github/CODEOWNERS` for `tests/quality/` protection
- [ ] Update `docs/sprints/QUALITY_STANDARDS.md` with baseline workflow

## Files to Create

| File | Purpose |
|------|---------|
| `tests/quality/_baseline.py` | Baseline loading, comparison, violation types |
| `tests/quality/_helpers.py` | Centralized file discovery, safe parsing |
| `tests/quality/baselines.json` | Frozen violation snapshot |
| `tests/quality/test_baseline_self.py` | Self-tests for infrastructure |

## Files to Modify

| File | Changes |
|------|---------|
| `tests/quality/test_code_smells.py` | Use `_helpers`, baseline enforcement |
| `tests/quality/test_stale_code.py` | Use `_helpers`, baseline enforcement |
| `tests/quality/test_test_smells.py` | Fix skipif bug, use baseline |
| `tests/quality/test_magic_values.py` | Fix path bug, use baseline |
| `tests/quality/test_unnecessary_wrappers.py` | Use `_helpers`, baseline |
| `tests/quality/test_duplicate_code.py` | Use `_helpers`, baseline |
| `tests/quality/test_decentralized_helpers.py` | Use `_helpers`, baseline |

## Key Design Decisions

### Stable Violation IDs

```
{rule}|{relative_path}|{identifier}[|{detail}]

Examples:
- high_complexity|src/noteflow/grpc/service.py|StreamTranscription
- thin_wrapper|src/noteflow/config/settings.py|get_settings|_load_settings
- stale_todo|src/noteflow/cli/main.py|hash:a1b2c3d4
```

### Baseline JSON Schema

```json
{
  "schema_version": 1,
  "generated_at": "ISO8601",
  "rules": {
    "rule_name": ["stable_id_1", "stable_id_2"]
  }
}
```

### Parse Error Handling

```python
# Never silently skip
tree, error = parse_file_safe(file_path)
if error:
    parse_errors.append(error)
    continue

# Fail at end if any errors
assert not parse_errors, "\n".join(parse_errors)
```

## Verification Commands

```bash
# Run quality tests
pytest tests/quality/ -v

# Generate baseline (after migration)
QUALITY_GENERATE_BASELINE=1 pytest tests/quality/ -v

# Check for new violations only
pytest tests/quality/ -v --tb=short
```

## Success Criteria

1. All quality tests pass with baseline enforcement
2. No `max_allowed` caps remain in test code
3. Self-tests cover all detection mechanisms
4. Parse errors fail loudly instead of silently
5. Detection holes (skipif, hardcoded paths) are fixed
6. `baselines.json` tracks all existing violations
