Vigil
← All news

v1.13.0 — fault drill-down: per-mechanic offenders + per-member top failures

The per-player aggregate ("Alice has 4 roots") and the per-mechanic histogram ("Cyclonic Break killed 6 people") were both top-level signals — but neither answered the actual diag…

Why

The per-player aggregate ("Alice has 4 roots") and the per-mechanic histogram ("Cyclonic Break killed 6 people") were both top-level signals — but neither answered the actual diagnostic question: who keeps eating which mechanic. The user's "I want to be able to see for every member what they most fuck up on" was the explicit driver. Both pivots ship together because they're the same underlying data.

Added — fault_breakdown_for_encounter()

analysis/fault_breakdown.py: walks fault_scores.reasons.deaths (populated by T-302 / v1.12.0 classifier) across all the static's watched wipes of an encounter and emits the joint (player × killing-ability) table. Each row carries deaths, fights_affected (distinct wipe ids), and a by_kind breakdown (root / cascade / mit_failure / enrage / unknown). Ability names resolved via one JOIN to abilities.

Added — GET /api/encounters/{id}/fault-breakdown

Context-scoped, single round trip. Both Home expansions pivot from the same payload client-side.

Added — expandable rows on Home

Both WipeMechanicsSection and FaultSection rows now have a ▸/▾ toggle:

  • "What's killing us": click a mechanic row → top 5 players who've died to it most, with per-player death count + wipe-count.
  • "Who's contributing to wipes": click a player row → top 5 mechanics they die to most, with Nx root / Nx mit-fail / Nx cascade / Nx unknown kind breakdown per row.

The breakdown is fetched once in ConsumerHome and shared down via props — single API call. Two pure pivot helpers (topOffendersForMechanic, topMechanicsForPlayer) keep the table-rendering logic clean.

Tests

  • 7 new in tests/test_fault_breakdown.py: empty-encounter zero shape; repeat-offender collapses to single row with deaths+fights_affected aggregated; ability name resolution; by_kind counts correctly (cascade detection works); rows sort by deaths desc; wipes_aggregated counts distinct wipes; cross-static isolation.
  • 446 tests passing (439 → 446, +7).

Note on the per-member view

The user-requested "for every member, what they most fuck up on" view is the per-player expansion on Home. The Members tab currently has only roster CRUD; surfacing this same data there is a natural follow-up but not needed for the current ship — the Home expansion already exposes the information.

No schema change. No new env vars.