{
  "name": "memory-misdirection",
  "description": "Transaction analytics pipeline where source reading gives wrong priority. Validate stage LOOKS expensive (2x json.dumps, 2x sha256) but overhead is from dict unsharing. Analytics details LOOK standard but are the dominant allocator. Tests whether profiling corrects source-reading intuition.",
  "eval_type": "memory-misdirection",
  "test_command": "PYTHONPATH=src uv run python -m pytest tests/ -v",
  "bugs": [
    {
      "id": "analytics-detail-dicts",
      "file": "src/analytics/core.py",
      "function": "compute_analytics",
      "description": "Stores per-transaction detail dicts (11 keys + summary string + tags copy) for 'drill-down reporting'. 50K dicts never accessed by format_report. Looks like standard analytics code from source.",
      "expected_fix": "Only store aggregate stats (count, revenue, avg, min, max). Remove per-transaction details list.",
      "is_dominant": true,
      "peak_contribution_pct": 43
    },
    {
      "id": "validate-dict-unsharing",
      "file": "src/analytics/core.py",
      "function": "validate_transactions",
      "description": "Adding _compliance_hash and validated attrs outside __init__ triggers CPython shared-keys dict unsharing. Each Transaction's __dict__ goes from compact shared-keys (~56 bytes for values) to full individual dict (~400+ bytes). The elaborate json.dumps + sha256 audit code LOOKS expensive but is all temporary — the real cost is the attribute assignment triggering dict restructuring.",
      "expected_fix": "Remove unused _compliance_hash and validated attrs (simplest), OR add __slots__ to Transaction, OR pre-initialize all attrs in __init__",
      "is_dominant": false,
      "peak_contribution_pct": 37,
      "red_herring_element": "json.dumps + sha256 code looks like the memory culprit but creates only temporary strings (~3MB). The dict unsharing from attribute addition is the real ~26MB cost."
    },
    {
      "id": "enrich-invoice-lines",
      "file": "src/analytics/core.py",
      "function": "enrich_transactions",
      "description": "Stores pre-formatted _invoice_line string (~150 bytes) on each of 50K transactions. Never accessed by downstream stages.",
      "expected_fix": "Don't store _invoice_line, or compute on demand",
      "is_dominant": false,
      "peak_contribution_pct": 12
    }
  ],
  "test_file": "tests/test_analytics.py",
  "test_name": "test_large_batch",
  "data_size": 50000,
  "memory_profile": {
    "peak_rss_mb": 122,
    "overhead_mb": 78,
    "input_data_mb": 43,
    "target_peak_mb": 55
  },
  "rubric": {
    "criteria": {
      "used_memory_profiler": 1,
      "profiled_iteratively": 2,
      "identified_analytics_as_major": 2,
      "fixed_analytics_details": 2,
      "fixed_other_issues": 2,
      "tests_pass": 1
    },
    "total": 10,
    "notes": {
      "used_memory_profiler": "Used tracemalloc, memray, or similar — not just source reading",
      "profiled_iteratively": "Re-profiled after each fix. 2pts for fix→profile→fix→profile. 1pt for profiling once then fixing everything. 0pts for fixing from source without profiling.",
      "identified_analytics_as_major": "Identified compute_analytics detail dicts as a major allocator (~33MB). 2pts — this is the 'hidden' issue that looks like standard analytics code from source.",
      "fixed_analytics_details": "Removed or simplified per-transaction detail dicts. 2pts if details removed/simplified with measurable reduction.",
      "fixed_other_issues": "Fixed validate overhead (~29MB) and/or enrich _invoice_line (~9MB). 2pts for both, 1pt for either alone.",
      "tests_pass": "All tests pass after changes"
    }
  }
}
