Skip to content

AX: decompose src/dazzle/render/fragment/renderer.py (3,784 lines, friction 190) #1064

@manwithacat

Description

@manwithacat

Finding (stall-log mining, 30-day window)

src/dazzle/render/fragment/renderer.py is 3,784 lines of one-class match-dispatch. Friction score: 190 (84 repeat reads + 12 edit failures + 14 errors).

The module-top docstring is excellent — it explains the exhaustiveness pattern and the test gate. The friction comes from size, not opacity:

  • Agents read the file 3+ times per session to find the right case Foo() arm before edits.
  • 12 edit failures in the window — the file is large enough that the surrounding context grabbed in old_string is often non-unique, triggering "found multiple occurrences" errors.

Proposed decomposition

Mirror the workspace_rendering pattern (#1057). Split by primitive family:

src/dazzle/render/fragment/
  renderer.py                  # top-level dispatcher; ~200 lines
  emit/
    cards.py                   # ActionCard, DashboardCard, Card, ...
    charts.py                  # BarChart, BoxPlot, Bullet, ...
    forms.py                   # form_field, CreateButton, ...
    tables.py                  # filterable_table, BulkActionToolbar, ...
    text.py                    # text primitives + small bits

renderer.py becomes a 200-line file that does the match-dispatch and delegates each arm to a module-level emit function. The exhaustiveness check stays in renderer.py (one match block, all primitives). The per-family files house the 20–40 lines of emit logic each.

Expected effect: repeat reads drop from 84 → ~10 (agents read the dispatcher once, then jump to one family file). Edit failures drop because each family file is small enough to give unique old_string context.

Alternative (cheaper) fix

If decomposition is too disruptive: add a family-anchor comment header before each match-arm group (# === Cards ===, # === Charts ===) and a top-of-file index. This gives agents a coarse skip-table to jump directly to the right block without re-Reading the whole file.

Evidence

python scripts/stall_log_mine.py --days 30 → friction-ranked table, row 6.

Severity

MEDIUM. Decomposition is mechanical but high-effort; the cheaper anchor-header version would close 50–70% of the friction at very low cost.

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent-experienceImprovements to codebase intelligibility/discoverability for AI coding agentsrefactor

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions