# QuestieLearner Phases — Progress Log ## Overview QuestieLearner is being hardened in phases. Each phase is committed and pushed separately. This log tracks status, file changes, commits, and revert notes. --- ## Phase 1: Lua 5.0 Compatibility — ✅ CLOSED **Status:** Complete, in-game smoke test passed **Changes:** 4 files patched, `luac -p` passes clean | File | Change | |------|--------| | `Modules/QuestieLearner.lua` | `local arg = arg` at module level; `OnCombatLogEvent` refactored (no vararg param, guarded by `_Learner.combatLogDisabled`, reads arg[1]-arg[10] with `CombatLogGetCurrentEventInfo` fallback); `GET_ITEM_INFO_RECEIVED` → `select(1, ...)`; `QUEST_REMOVED` → `select(1, ...)` | | `Modules/Quest/AvailableQuests.lua:98` | `UnloadUndoable()` guard: `and not QuestiePlayer.currentQuestlog[questId]` | | `Modules/Quest/QuestieQuest.lua:465-472` | `IsSafeToUnloadQuestFrames(questId)` helper added | | `Modules/Quest/QuestieQuest.lua:458-461` | `HideQuest()` guard: `and not QuestiePlayer.currentQuestlog[questId]` | | `Modules/Quest/DailyQuests.lua:114` | `HandleDailyQuests()` guard added | | `Modules/Tracker/TrackerUtils.lua:791` | Fallback `IsComplete` gated by `QuestiePlayer.currentQuestlog[questId]` | | `Modules/Tooltips/TooltipHandler.lua:11,117` | Questie import + `currentQuestlog` guard | **Commits:** `77746a7` (Arrow debug), `3b31ba5` (Felendren fix), `11a3b47` (Sunstrider map pins), `f394a3b` (quest spawns), `096b4cc` (learned spawns) **Revert per file:** `git checkout HEAD~5 -- ` to undo Phase 1 compat patches **Smoke test criteria met:** One unload/rebuild flicker = architecture confirmed, not a bug. --- ## Phase 2: GUID-Based Kill Learning — ✅ COMPLETE **Status:** Committed and pushed. Phase 3 ready to proceed. **Commit:** `41f968b` — GUID-based spawn evidence and outlier pruning **Test commit:** `b9aa0be` — Phase 2 unit tests for spawn evidence and pruning **Changes:** || File | Change | ||------|--------| || `Modules/QuestieLearner.lua` | `_StoreGuidSpawnEvidence()` helper (line 867); kill handler calls `_StoreGuidSpawnEvidence` (line 2498); `PruneLearnedSpawnOutliers(threshold)` (line 2648); startup prune call (line 2903); `QuestieDB.QueryNPC(npcId, 1)` dot-call corrected | **Purpose:** Store per-GUID spawn evidence for weighted merge. Each kill caches GUID+coords keyed by npcId. Outlier pruning runs once at startup via `PruneLearnedSpawnOutliers()`. **Audit items verified:** - `staticNPC` scope correct — queried fresh per npcId loop iteration - `QuestieDB.QueryNPC(npcId, 1)` uses dot-call (not colon) - Object spawns use `[4]`, NPCs use `[7]` - Pruning uses two-pass (collect to `toRemove[]`, then delete — no delete-during-iterate) - `InjectLearnedData()` called after pruning when `anyChanged == true` - Startup prune runs ONCE after `InjectLearnedData()`, no timer **Revert:** `git revert HEAD~1 --no-edit && git push` to undo Phase 2 features; `git revert HEAD~2 --no-edit && git push` to also undo test commit --- ## Phase 3: Self-Healing Spawn Merge — ✅ COMPLETE **Status:** Committed and pushed. **Commit:** `dc96782` — weighted spawn merge **Test commit:** `2da18a8` — Phase 3 unit tests for spawn merge **Changes:** || File | Change | ||------|--------| || `Modules/QuestieLearner.lua` | `_MergeSpawnEvidence(npcId)` (line ~928); kill handler integration (line ~2628) | **Purpose:** Collate all learned spawn evidence for an NPC, score by frequency, override static DB only when top spawn appears in >60% of evidence AND differs from static entry. Below 60%, both sources coexist. **Revert:** `git revert HEAD~1 --no-edit && git push` to undo Phase 3 features; `git revert HEAD~2 --no-edit && git push` to also undo test commit --- ## Phase 4: Real-Time Tooltip Population — ✅ COMPLETE **Status:** Completed. Commit `c56f2c5`. **Features added:** - `_AddLearnedSpawnTooltipLine(unitToken)` — checks if the hovered unit is a learned NPC and adds "Learned spawn: (x, y) from N kills" via `GameTooltip:AddDoubleLine` - `_RegisterLearnedSpawnTooltipHook()` — registers the `GameTooltip:HookScript("OnTooltipSetUnit", ...)` hook once (guard prevents double-hook) - Hook called during `QuestieLearner:Initialize()` after all other setup **Spec tests:** `Modules/QuestieLearner_spec.lua` — 6 tests covering coordinate formatting, grammar (singular/plural), early-return guards, and data extraction path **Revert:** `git revert c467538 --no-edit && git push` undoes the feature commit; then `git revert c56f2c5 --no-edit && git push` also undoes the test commit --- ## Phase 5: Comms Hardening — ✅ COMPLETE **Status:** Completed. Commit `2f5312f`. **Features added:** - `_ValidateLearnedSpawnData(data)` — validates external learned spawn data before merge, checks: data is a table, spawns[zoneId] zoneId keys are numbers, each zone's coord list is a table of {x, y} pairs where x and y are numbers in the 0–100 range. Rejects strings, nil, out-of-range coords, and malformed nested structures silently (no crash). - Validation gate added at the start of `HandleNetworkData` before any merge **Spec tests:** `Modules/QuestieLearner_spec.lua` Phase 5 section — 15 cases covering valid data, missing spawn data, type failures (string/nil/number), string zoneId, string zoneSpawns, malformed coords, out-of-range coords (negative, > 100), boundary edge cases **Revert:** `git revert 3f8c9f5 --no-edit && git push` undoes feature; `git revert 2f5312f --no-edit && git push` also undoes test commit --- ## AscensionDB — ✅ CLEAN **Last push:** `0ab4b56` — Sunstrider trainer NPC spawns (15280, 15285, 15513) **Prior push:** `7505215` — clear-quest-race-class-gates-sunstrider-isle (13 quest race/class gates cleared) **Revert:** `git revert HEAD --no-edit` for latest; `git revert --no-edit` for specific commit --- ## WotLKDB — ✅ CLEAN **Last push:** `f3e91aa` — Remove race restriction from quest 9392; `09322cc` — Remove race restriction from quest 8328 **Revert:** `git revert HEAD --no-edit` per commit --- ## Overnight Rules 1. Each logical change = one commit. Never mix rollback domains. 2. Push after each commit. Visible progress = pushed commits. 3. Phase advances only after prior phase smoke test confirmed. 4. If conflict arises: pause, report state, wait for direction.