Vigil
← All news

v1.16.5 — Per-phase tabs use wipe counts; phase inference for "Unknown"; guessed-pill tooltip distinguishes mechanic vs phase

User feedback on v1.16.4: "The table all (X) should be for wipes not death" + "how are there unknowns? Use the timeline of the report and cactbot's timeline, taking into account d…

Why

User feedback on v1.16.4: "The table all (X) should be for wipes not death" + "how are there unknowns? Use the timeline of the report and cactbot's timeline, taking into account differences in kill times between phases to guess" + "under the guessed icon make it so that if you hover over it you can see what was guessed. Right now we have mechanic guessed and we will have phase guessed".

Changed — chip counts now show wipes, not deaths

analysis/cartography.py response now includes wipes_by_phase: {phase: count} — a tally of Fight.last_phase across the static's watched wipes. web/src/Home.jsx uses these counts in the phase chips: All (467 wipes), P2 (262 wipes), etc. Tooltip on each chip explains what the number means ("N wipes ended in PX").

Added — phase inference for "Unknown" buckets

Per-bucket phase resolution priority:

  1. T-103 per-pull inference — for each death, look up which T-103 phase boundary contains the death's timestamp in that fight. Most accurate when events are ingested per fight; falls through silently when they aren't.
  2. cactbot_phase_label — parsed from the v1.3.0 annotation (e.g. 'P3' → 3). Reliable per-ability fallback.
  3. fight_model.phase when raw ≥ 1 (i.e. promoted phase ≥ 2) — consensus; less trusted because some encounters were cloned with bulk-tagged 0 defaults.
  4. None → genuine "Unknown" tab.

Per bucket: phase_source{fight_model, inferred, unknown} + phase_inferred_deaths count. When T-103 / cactbot OVERRIDE a stale fight_model phase, the bucket is marked inferred.

Changed — phase numbering normalized to 1-indexed throughout

The output bucket.phase and the chip labels are now both 1-indexed (P1, P2, ...) — matching FFLogs Fight.last_phase and cactbot's labeling, which is what users see in-game. Previously fight_model.phase was 0-indexed (so a bucket displayed as "P0" while the chip showed "P1" — confusing mismatch). bucket.fight_model_phase keeps the raw 0-indexed DB value for back-compat. T-103 phase indices are also 0-indexed internally; we +1 on output.

UI — guessed pill differentiates mechanic vs phase

The yellow guessed pill on each cartography row now has two faces:

  • mechanic guessed / N mech-guess — non-attributable deaths whose killing ability was inferred (v1.16.1/v1.16.3 work).
  • phase guessed / N phase-guess — deaths whose phase came from T-103 or cactbot rather than fight_model consensus.

Both can show together (N mech-guess · M phase-guess). Tooltip explains the inference source for each.

In the table's Phase column, buckets with phase_source === 'inferred' get a small ? indicator next to the phase number with a tooltip noting the phase was guessed.

Tests

3 new in tests/test_cartography_phase_inference_v1_16_5.py: wipes_by_phase shape, fight_model phase passthrough (with 1-index normalization), unknown phase when nothing is available. 516 tests passing (513 → 516, +3).

Live AC against DSR data

  • wipes_by_phase: P1=37, P2=262, P3=76, P4=15, P5=38, P6=31, P7=8 (total 467, matches total_wipes).
  • Buckets now show consistent P1+ labels. Where the dev DB's fight_model.phase=0 bulk-tagged values were getting overridden by cactbot (e.g. Skyblind), phase_source is inferred with phase_inferred_deaths set.

Note on DSR data quality

The dev DB's DSR fight_model was bulk-cloned from encounter 1065 without re-running phase consensus, so most rows have phase=0 (or no cactbot_phase_label). Inference helps but the underlying consensus is sparse — running T-203 + cactbot annotation against 1076 specifically would give cleaner phase tags. Not in scope here.