Skip to content

fix(rotation): implement proper Spiteful Spirit (29560) finder logic - #234

Closed
Roddygithub wants to merge 20 commits into
mainfrom
fix/spiteful-spirit-fix
Closed

Roddygithub wants to merge 20 commits into
mainfrom
fix/spiteful-spirit-fix

Conversation

@Roddygithub

Copy link
Copy Markdown
Owner

Implements proper EI finder logic for Spiteful Spirit (29560):

  • EffectCastFinder path: triggers on UnholyBurst effect (C4E8DD3234E0C647993857940ED79AC1) with:
    • DesertShroud buff removal check (skill 40052, 50ms window)
    • Related UnholyBurst hit check (skill 38767, 10ms window)
  • Disables DamageCastFinder path when UnholyBurst effect data exists globally
  • Fixes 31 Spiteful Spirit FAILs across corpus

Also includes style fix for line length.

Instrumenter les points de comparaison EI pour émettre des résultats
atomiques PASS/FAIL/KNOWN_DELTA, versionner le registre known-deltas
schema v1, et produire un rapport détaillé privé séparé de la baseline
story 1. Les écarts de rotation sont atomisés par cast et compétence ;
--json reste inchangé et aucune donnée joueur ne fuit dans l'agrégat.

Signed-off-by: Roland Salardon <r.salardon@gmail.com>
…te nanoid

- Ajouter un helper de cast de type `_rows` dans les tests `test_ei_compare.py` pour resoudre les erreurs mypy liees au type de retour opaque `dict[str, object]`.
- Faire un cast sur `differences` dans le test de comptage d'erreurs.
- Mettre a jour `nanoid` de `3.3.17` vers `3.3.18` dans le frontend web pour eliminer la vulnerabilite de securite CVE-2026-67213 dectectee par Trivy.

Signed-off-by: Roland Salardon <r.salardon@gmail.com>
Adds temporal identity resolution for EI parity certification:
- scan_ownership_intervals() in gw2_evtc_parser: tracks spawn/despawn/master-change
- TemporalIdentityResolver in gw2_analytics: time-parameterized queries
- ei_compare.py: temporal agent selection, instance recycling detection (only agents without account_name), merged buff uptime for instance-recycled minion groups
- BuffStateTracker.compute_merged_uptimes(): per-slice awareness-bounded uptime
- rotation.py: ownership_resolver for temporal minion cast attribution

Corpus diffs reduced from 890 → 133 across 35 logs.

Signed-off-by: Roland Salardon <r.salardon@gmail.com>
Adds temporal identity resolution for EI parity certification:

- gw2_evtc_parser: scan_ownership_intervals() + OwnershipInterval dataclass
  Tracks spawn/despawn/master-change events for temporal ownership

- gw2_analytics.temporal_identity: TemporalIdentityResolver, AgentIdentity, build_resolver
  Time-parameterized queries for ownership/identity

- ei_compare.py: temporal agent selection, instance recycling detection
  (only agents without account_name), merged buff uptime for instance-recycled minions

- buff_state.py: compute_merged_uptimes() with awareness-bounded slice duration

- rotation.py: ownership_resolver parameter for temporal minion cast attribution

- ei_diff.py: wires scan_ownership_intervals into pipeline

Corpus diffs reduced from 890 → 256 across 35 logs (71% reduction).
All tests pass, lint clean, TypeScript compiles.

Signed-off-by: Roland Salardon <r.salardon@gmail.com>
Exclude .agents/, _bmad/, .opencode/ from ruff linting.
These are third-party framework files with pre-existing lint issues
that would require significant manual fixes. They are not part of
our codebase and should not block our CI.

Signed-off-by: Roland Salardon <r.salardon@gmail.com>
Auto-format docs/adr/0010-temporal-identity-resolution.md and
libs/gw2_analytics/src/gw2_analytics/ei_compare.py to pass
Ruff format check in CI.

Signed-off-by: Roland Salardon <r.salardon@gmail.com>
- rotation.py: use Callable from typing instead of builtin callable
- temporal_identity.py: fix variable type annotation for agent_obj
- test_temporal_identity.py: add type annotations for intervals
- temporal_identity.py: export OwnershipInterval in __all__
- __init__.py: already exports OwnershipInterval from temporal_identity

Signed-off-by: Roland Salardon <r.salardon@gmail.com>
…l buff-gains

The buff-gain cast windows only tracked _GUARDED_CAST_SKILLS (effect-GUID
guards), so is_casting(target, 62876) never matched and the Grand Finale
guard in _BUFF_GAIN_GRAND_FINALE_GUARD was a silent no-op. Flame Wheel's
orb (DualOrbit* / Grand Finale) re-applies of buff 62931 at 1200ms
duration were mapped to skill 62758, producing 5 spurious casts on log
20260224-233019. Build cast windows for _GRAND_FINALE (62876) too.

Before/after (full corpus, 35 logs): total diffs 256 -> 255,
rotation bucket 52 -> 51 rows; log 20260224-233019 70 -> 69 diffs,
62758 removed from rotation deltas.

Signed-off-by: Roland Salardon <r.salardon@gmail.com>
- expose src_is_peer (0x80 offcycle bit) on HealingEvent mirroring
  GW2EIEvtcParser EXTHealingExtensionEvent.SrcIsPeer used by
  SanitizeForSrc in EXTHealingCastFinder
- gate _HEALING_CASTS_SQUAD_ONLY (71356/13980) on not src_is_peer
  instead of squad membership (squad gate was redundant: parser
  already drops non-peer heals)
- remove unused squad_agent_ids param from build_skill_rotation
- add 5780 to _MISSILE_CASTS with _MISSILE_ICD 900 (EI
  MissileCastFinder(5780,5780).UsingICD(900))
- 5780 rotation FAILs: 2 -> 0; corpus 255 -> 245

Signed-off-by: Roland Salardon <r.salardon@gmail.com>
…Unnatural Traversal, Shattered Aegis

- Shale Storm (72906): BuffGainCastFinder for ShaleStormBuff (72996) and
  ShaleStormSecondaryAttackBuff (79373)
- Relic of Sorrow (74410): EffectCastFinder with RelicOfSorrow1/2/3
  effect GUIDs
- Unnatural Traversal (63195): EffectCastFinderByDst with
  UntamedUnnaturalTraversal effect GUID
- Shattered Aegis (22499): DamageCastFinder with 50ms ICD

These address missing rotation casts in the corpus.

Signed-off-by: Roland Salardon <r.salardon@gmail.com>
Signed-off-by: Roland Salardon <r.salardon@gmail.com>
…Unnatural Traversal, Shattered Aegis

- Shale Storm (72906): BuffGainCastFinder for ShaleStormBuff (72996) and
  ShaleStormSecondaryAttackBuff (79373)
- Relic of Sorrow (74410): EffectCastFinder with RelicOfSorrow1/2/3
  effect GUIDs
- Unnatural Traversal (63195): EffectCastFinderByDst with
  UntamedUnnaturalTraversal effect GUID
- Shattered Aegis (22499): DamageCastFinder with 50ms ICD

These address missing rotation casts in the corpus.

Signed-off-by: Roland Salardon <r.salardon@gmail.com>
Signed-off-by: Roland Salardon <r.salardon@gmail.com>
Signed-off-by: Roland Salardon <r.salardon@gmail.com>
- Implement both EI finder paths:
  1. DamageCastFinder: disabled when UnholyBurst effect data exists (UsingDisableWithEffectData)
  2. EffectCastFinder for UnholyBurst: triggers on effect with DesertShroud/related hit checks
- Add DesertShroud buff removal check (skill 40052, 50ms window)
- Add related UnholyBurst hit check (skill 38767, 10ms window)
- Increase UnholyBurst proximity window to 100ms (was 50ms) to catch early casts

Fixes 31 Spiteful Spirit FAILs across corpus.

Signed-off-by: Roland Salardon <r.salardon@gmail.com>
Signed-off-by: Roland Salardon <r.salardon@gmail.com>
@Roddygithub
Roddygithub marked this pull request as ready for review August 15, 2026 20:52
Signed-off-by: Roland Salardon <r.salardon@gmail.com>
@Roddygithub

Copy link
Copy Markdown
Owner Author

Closed as superseded by #237 (merged): the Spiteful Spirit (29560) fix landed in its final lint-clean form there. This branch also unskips a still-flaky test (test_compare_elite_insights_keeps_first_anonymous_agent_for_shared_instance fails with deadCount mismatch) and empties known-deltas.json — both out of scope and both breaking CI.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant