1.0.1-release
What's new
tag b9cd704c846a2d6b31f4335b1c9d6d17b4662585 1.0.1-release
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 22:03:30 2026 +0530
commit 759dc5d79755dfb9935b321677cf1ff5a0ec47cc
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 22:00:24 2026 +0530
Release 1.0.1: version bump, release notes and the gated release run
- Version 1.0.0 -> 1.0.1 in the TOC, NS.version, the version assertions in
tests/test_setups.lua, and the version examples in module-map, debug and
smoke-tests.
- README: a 1.0.1 Version History row (the blank bar-name font fix, #24),
a de-AI pass over the intro and the screenshot captions, and the Usage,
"How the containers work" and bug-report steps as bullet lists.
- Release run 20260927-214918 at b5208f3: lint 0/0 over 146 files, 1702/1702
tests, 11 perf scenarios, complexity with 0 functions above CCN 15. The
bundle's ANALYSIS.md is written. On the RESULTS.md watch list,
tests/test_style_text.lua (newly in the 1000-1500 band) is ruled on and
the modules/Style.lua disposition is refreshed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit b5208f35fb09a2b3399d7357cbd2e9b2e9226c7a
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 21:49:17 2026 +0530
Automated tests: refused 1.0.1 release run 20260927-214805
The release gate refused 1.0.1 because one test failed: the eol test found
docs/perf-analysis/20260927-214132/dump.json with a bare LF on disk where
.gitattributes declares CRLF. A shell-redirect write caused it. The committed
bytes were right, and re-checking out the file repaired the working copy.
This commit keeps the refused run as the record of that attempt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 4e03d414af2dd8d4ac909cc5949b9873371c4511
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 21:46:35 2026 +0530
Perf: in-game capture 20260927-214132 (Protection Paladin, Murder Row, 1.0.0 post-release build)
Third capture in the store, and the first on 1.0.0. The addon's own Lua cost
0.262 ms per second of combat, 94% of it styleElement. The frame-time delta
(-0.85 ms/frame) runs backwards, with two loading screens between the arms,
so it measured the environment. The capture index in the README gains a row.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 6e84e0652a5756a37c38c16f040abcc60601105d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 21:29:28 2026 +0530
Remove dead Anchors exports; mark FramePicker.IsActive a test seam
No production code called any of these (git grep); owner-requested cleanup.
- Anchors.IsEdge: deleted (zero callers).
- Anchors.EdgeAllowed: deleted, with the edges case that exercised only it
and the one assertion in the points behind case (whose AttachEdge and
placement checks stay, red-under note reworded to them).
- Anchors.ParseEdge: deleted, with its assertions in the EDGES case.
- Anchors.DerivedPoints: deleted; the derived-points cases in
tests/test_anchors.lua now call EdgePoints(L, "after-start"), and the
edges equivalence case keeps pinning EdgePoints to the pre-batch-9 points
without the DerivedPoints lines.
- Anchors.DefaultEdge: deleted; the file-private defaultToken it wrapped
stays. Its test assertions now check the public AutoPoints pair against
EdgePoints of the expected token (justify, growth flip, bars defaults).
- FramePicker.IsActive: kept, doc comment marked "(a test seam)".
- Docs and comments naming the deleted functions (module-map, settings-panel,
data-flow, schema, the Anchors_Attach header) now describe the behavior via
defaultToken / AutoPoints / EdgePoints.
- Tests 1703 -> 1702: docs/test-cases.md regenerated, README badge updated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 6e84e0652a5756a37c38c16f040abcc60601105d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 21:29:28 2026 +0530
Remove dead Anchors exports; mark FramePicker.IsActive a test seam
No production code called any of these (git grep); owner-requested cleanup.
- Anchors.IsEdge: deleted (zero callers).
- Anchors.EdgeAllowed: deleted, with the edges case that exercised only it
and the one assertion in the points behind case (whose AttachEdge and
placement checks stay, red-under note reworded to them).
- Anchors.ParseEdge: deleted, with its assertions in the EDGES case.
- Anchors.DerivedPoints: deleted; the derived-points cases in
tests/test_anchors.lua now call EdgePoints(L, "after-start"), and the
edges equivalence case keeps pinning EdgePoints to the pre-batch-9 points
without the DerivedPoints lines.
- Anchors.DefaultEdge: deleted; the file-private defaultToken it wrapped
stays. Its test assertions now check the public AutoPoints pair against
EdgePoints of the expected token (justify, growth flip, bars defaults).
- FramePicker.IsActive: kept, doc comment marked "(a test seam)".
- Docs and comments naming the deleted functions (module-map, settings-panel,
data-flow, schema, the Anchors_Attach header) now describe the behavior via
defaultToken / AutoPoints / EdgePoints.
- Tests 1703 -> 1702: docs/test-cases.md regenerated, README badge updated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit b5f65a3a753b0998132b5cef52003b7e97787c74
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 21:10:38 2026 +0530
Sync docs for the font primer before merge (#24)
- ARCHITECTURE, performance: nine lifecycle events, not eight; the
stand-down list names EmptyWatch.Stop and the primer's Stop, and the
primer's refresh includes the system apply after UpdateAllAuras.
- data-flow, midnight-quirks, module-map, debug: a font the client
refuses is retried (FP-07); the Diag row names the refused list and the
loading-screen timing line.
- common-tasks: a new font block goes into FontPrimer's BLOCKS.
- DEPENDENCIES: two drifted line citations; ARCHITECTURE: the untagged
revendor bundle; smoke-tests: the duplicated checks 58/59 relabeled 58a/59a.
- Comment-only, owner-confirmed: CastAura help-level field is
entry.help.level; GeneralSpells cites Options.lua:513-519;
NS.ContainerSection is a test seam.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit b5f65a3a753b0998132b5cef52003b7e97787c74
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 21:10:38 2026 +0530
Sync docs for the font primer before merge (#24)
- ARCHITECTURE, performance: nine lifecycle events, not eight; the
stand-down list names EmptyWatch.Stop and the primer's Stop, and the
primer's refresh includes the system apply after UpdateAllAuras.
- data-flow, midnight-quirks, module-map, debug: a font the client
refuses is retried (FP-07); the Diag row names the refused list and the
loading-screen timing line.
- common-tasks: a new font block goes into FontPrimer's BLOCKS.
- DEPENDENCIES: two drifted line citations; ARCHITECTURE: the untagged
revendor bundle; smoke-tests: the duplicated checks 58/59 relabeled 58a/59a.
- Comment-only, owner-confirmed: CastAura help-level field is
entry.help.level; GeneralSpells cites Options.lua:513-519;
NS.ContainerSection is a test seam.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 21262c051628d553b54fdff056edd124b828ca90
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 20:59:04 2026 +0530
FP-07: checkpoint
Battery at FP-07: 1703/1703 sharded and -j 1; lint 0 warnings / 0 errors
in 146 files; complexity 0 functions above CCN 15 (whole repo); perf.lua
ok; docs/test-cases.md byte-identical to --list; README badge 1703/1703.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit beb71a72239e0d3186a0bec985b5d8c5ddcf69ff
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 20:57:30 2026 +0530
FP-07: address review: the refused-font report test counts SetFont calls, so a report that retries goes red
primerRefuses now returns a counter of the primer frame's SetFont calls. The
refused= diagnostics test asserts the count is unchanged across build(NS),
which is what a retry of the permanently refused font would change; its
timer and primed-count asserts could not see one. Checked against the
reviewer's mutant (primerLine calling FP.PrimeAll first): the test now fails.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 70d7f3c534af5657ada521cfbf9fe371256f5390
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 20:52:27 2026 +0530
FP-07: A font the client refuses is retried, not dropped: every priming and the loading screen's end try it again (#24)
The owner's run of 6994c46 passed, but /am diagnostics read "fonts primed:
1 [Ka0s Kait.ttf 36 THICKOUTLINE]": every Ka0s Prototype triple was
missing. primeBlock marked a triple seen before its SetFont and dropped it
silently when the client refused the font, so a font refused at
PLAYER_LOGIN was never primed again.
- A triple is marked primed only when SetFont accepts it; a refused one goes
on a deduplicated refused set and every later PrimeAll retries it on the
one font string it was first tried on.
- OnLoadingScreenEnd (and the PLAYER_ENTERING_WORLD fallback) run a priming
pass before arming the world hide and refresh.
- One Fonts debug line per priming that met a refusal, counts only.
- Diagnostics: the fonts primed line ends refused=<n> [...].
- Addendum, debug.md, known limitation, smoke check FP11.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 6994c4646c45d02cdd7b623e29765d1712b5dcf5
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 20:09:24 2026 +0530
FP-06: checkpoint
Battery at 94a4c66: 1695/1695 sharded and -j 1; lint 0 warnings / 0 errors
in 146 files; complexity 0 functions above CCN 15; perf.lua ok;
docs/test-cases.md byte-identical to --list; README badge 1695/1695.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 94a4c66a7f2574f3c9a95ea3ee5c650e42a3d2cf
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 20:07:27 2026 +0530
FP-06: address review: time the world hide and refresh from LOADING_SCREEN_DISABLED, not PLAYER_ENTERING_WORLD
The client fires PLAYER_ENTERING_WORLD while the loading screen is still up and
LOADING_SCREEN_DISABLED when it ends, seconds later on a slow or cold-cache
login. Timers counted from PEW could hide the prime frame and run the refresh
under the loading screen again, leaving the login auras blank.
- LOADING_SCREEN_DISABLED joins LIFECYCLE_EVENTS (through NS.SafeRegisterEvent);
addon:OnLoadingScreenEnd calls FontPrimer.OnLoadingScreenEnd, which arms
WORLD_HOLD and WORLD_REFRESH. FontPrimer.OnEnterWorld now only notes the time,
and is the anchor itself only on a client that refused the event
(NS.RejectedEvents).
- A [Fonts] trace line gives both timestamps and the gap; since logging is off
at login, the diagnostics header also gains a "loading screen:" line
(DiagState enteredAt / screenEndAt) that FP10 records.
- Tests: PEW and LOADING_SCREEN_DISABLED more than WORLD_HOLD apart; the PEW
fallback; the login, later-screen, Stop and DiagState cases now fire both
events; lifecycle counts eight -> nine; the report line.
- Docs: ARCHITECTURE, data-flow, debug, midnight-quirks, module-map,
performance and FP10 name the real anchor; shifted core/AuraMaster.lua
citations fixed; test-cases.md regenerated, badge 1695.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit bfc8c96dcd68ad4ee4fe861c9702f82872c34a35
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 19:54:56 2026 +0530
FP-06: Font primer survives the loading screen: a login priming waits for PLAYER_ENTERING_WORLD (#24)
The owner's first in-game run of cbdd82f: auras cast after login drew, but the
auras present at login stayed blank until /reload. The priming at PLAYER_LOGIN
runs under the loading screen, and its 1 s hide and 0.5 s refresh both ran
before the loading screen ended, so nothing was drawn in the font until the
login auras themselves.
- A PrimeAll before the first PLAYER_ENTERING_WORLD shows the frame and arms
nothing; FontPrimer.OnEnterWorld (from addon:OnEnterWorld) arms the hide at
WORLD_HOLD (2.0 s) and the refresh at WORLD_REFRESH (1.5 s) when anything was
primed since the last loading screen, then clears that mark.
- A PrimeAll during play keeps the HOLD/REFRESH path. Stop cancels every timer
and ends the wait for the world (a stood-down addon hears no PEW).
- DiagState gains `state`; the diagnostics line reads refresh=armed,
armed-world, awaiting-world or idle.
- Docs: debug, performance, midnight-quirks, ARCHITECTURE, data-flow,
module-map; smoke check FP10; citations shifted in core/AuraMaster.lua fixed.
- Includes the FP-06 addendum plan.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit cbdd82faf31580aeea7c7a52dcdadcadf19a5ebb
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 19:34:54 2026 +0530
FP-05: final checkpoint
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 2fb1abe62fcfaeab28faf24b948d5b301f3164f8
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 19:32:16 2026 +0530
FP-04: address whole-branch review: the refresh re-applies for addon-written text; primer tests tightened; real font names in docs
- FontPrimer's refresh now also issues one system apply of every container
(CM.RequestApply(nil, true)), so the name label, a Text line's literal pieces and
the test-mode placeholders, which an apply writes once and nothing rewrites, are
written again in the loaded font. UpdateAllAuras stays gated to live, shown,
non-previewing instances.
- Tests: the recorder frame starts hidden, so the Show call is pinned, and a later
triple re-shows the frame after HOLD; the walk gives bars.time a triple of its
own; a refused SetFont is not counted, listed, traced or refreshed for; the
refresh's stood-down gate; the frame's off-screen anchor; the refresh re-writes
a label and re-applies a previewing container.
- Docs: primed-font names as the real files (Ka0s Prototype.ttf, Ka0s Kait.ttf) in
debug.md, FP6 and the fixtures; new smoke check FP9 (label and Text literals on an
addon font); the applyPass citation is 324-332; data-flow and module-map describe
the re-apply. 1685 cases.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit dd387b743a532fbaa991f2ee1b007ade487d1f17
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 19:16:53 2026 +0530
FP-03: address review: the fonts primed case fires the refresh alone, so its hold-timer note holds
The 'fonts primed ... refresh state' diagnostics case claimed it went red if DiagState read the
refresh from the hold timer, but __fireTimers fires both timers at once, so it could not tell
them apart. The case now fires only the 0.5 s refresh (taken off the queue), asserts the 1 s hold
timer is still armed, and asserts refresh=idle before the full fire. Verified: with DiagState
changed to `refresh = holdTimer ~= nil`, this case now goes red.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 70c869484edfc810d155cb38c9ba072fd3470926
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 19:09:21 2026 +0530
FP-03: Diagnostics fonts primed line; docs rewritten around the lazy font load (#24)
Spec P3: the /am diagnostics header gains
"fonts primed: <n> [<file> <size> <flags>, ...] refresh=<armed|idle>",
read from FontPrimer.DiagState (state only: it primes nothing and arms
nothing), each triple by its file's name, `-` for no flags, the list
capped at Diag.MAX_IDS with the per-list cap flagged, printed while
stood down and while auras are secret. Five new cases in
tests/test_diagnostics.lua. The Fonts trace line landed in FP-02.
Spec P4: debug.md's "Bar names that do not show" explains the lazy font
load, the primer and the new line (Diag row and example updated).
midnight-quirks.md has a measured 2026-09-27 section on the lazy font
load that keeps the engine's write-once fact, and a taint note for the
primer's frame. ARCHITECTURE.md counts 54 files and 18 modules, and
covers the primer's wiring, CONFIG_CHANGED order, taint and limitation
prose. data-flow.md gains the primer in the pipeline, the lifecycle, the
stand-down table and a "Priming the fonts" section. module-map.md,
performance.md (the primer's one-off cost; buckets unchanged) and
known-limitations.md (a font registered after login) are updated.
smoke-tests.md adds "Font primer (2026-09-27, owner to run)", checks
281-288, where the removed BN checks started. No stale repaint claims
left outside the frozen records. docs/test-cases.md regenerated; README
badge at 1681/1681.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit dd6d7aed2fd8f7d0f6fa1e98bcbb925190af273b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 19:00:32 2026 +0530
FP-02: address review: the measures resolve their font through Style.FontKey; drifted Style.lua citations
TimeTextWidth, WidestLine and PiecePadding each carried a verbatim copy of the
font resolution; they now call Style.FontKey, so the primed key and the measured
key cannot drift apart. A test pins all three to FontKey. The comment citation in
settings/GeneralSpells.lua (Style.lua:899, drifted by FP-02) and the doc
citations shifted by this change are corrected. Tests 1675 -> 1676.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 6d0489cb972b93fee4a4ac4b7e62a2a7a0065681
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 18:50:12 2026 +0530
FP-02: Font primer: draw every container font once on a shown frame (#24)
modules/FontPrimer.lua (NS.FontPrimer, spec P2). PrimeAll collects every
(file, size, flags) triple the active profile's containers use, enabled
or not (bars name/time/stacks, icons time/stacks, text.font, label.font),
skips Fonts\ paths, and draws each new one with SAMPLE on one shown 1x1
frame on UIParent placed above the screen, hidden HOLD (1.0 s) later by a
cancellable C_Timer.NewTimer. When anything new was primed it arms one
refresh REFRESH (0.5 s) later, which runs inst:Refresh() on each live
instance with an engine that is neither parked nor stale and is shown
and not previewing; re-arming restarts it. Nothing runs while stood
down; Stop cancels both timers and hides the frame, and the primed set
survives. DiagState reads the primed triples and the refresh state for
FP-03's diagnostics line. One NS.Debug("Fonts", ...) line per PrimeAll
that primed something.
Style.FontKey (added at the end of Style.lua) is the one font
resolution: ApplyFont now uses it, so the primed triple is the one the
text sets.
Wiring: PrimeAll at the end of CM.StartListening (login and stand-up,
before the first build), in the CONFIG_CHANGED handler before the apply
is requested, and in CM.Announce before CM.Sync, because a profile
switch sends no CONFIG_CHANGED (the spec lists it under that handler).
Stop in CM.StopListening.
TOC entry with a Conventional note; module-map rows for the module and
the suite. New suite tests/test_fontprimer.lua (13 cases) covers the
spec's Testing list apart from the diagnostics line (FP-03); the
test_disabled census and timers hold. Doc line citations shifted by
the ContainerManager and Style edits are updated. docs/test-cases.md
regenerated; README badge at 1675/1675.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit d8195e4ee69d5e227a05b8c929a5e5154eb036e6
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 18:37:37 2026 +0530
FP-01: Remove NameRepaint and everything that exists only for it (#24)
The repaint answered a symptom: the cause is the lazily loaded addon
font (findings, "Correction"). Removed modules/NameRepaint.lua and its
TOC entry, the Sync calls in CM.FlushPending and CM.ApplyVisibility, the
OnEnterWorld hook, the Arm calls in OnUnitSwap and OnUnitPet, the
stand-down Stop, the nameRepaint perf bucket, the tests/perf.lua
scenarios, tests/test_namerepaint.lua, the name repaint diagnostics line
and its tests, and Style.ShowsEngineName. test_disabled, test_perf and
test_emptywatch are back to master's counts; the wiring files and the
docs NR-03/NR-05 changed are back to master, so their line citations
are too.
Kept: the removal of the cee5bb6 width fields and
Style.MeasuredTimeWidths (one test proves them gone), the shared
TT.Compile refusal, the EmptyWatch refused-event notes in
midnight-quirks.md, and the findings. debug.md's "Bar names that do not
show" is a short pointer to the findings until FP-03. module-map.md now
counts seven perf buckets. docs/test-cases.md regenerated; README badge
at 1662/1662.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 86a89d2b5ba9cf5173cbe6af1ff1c413d0ab7578
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 18:32:31 2026 +0530
FP-00: The real cause is the lazy-loaded font; font primer design and plan (#24)
Owner A/B (Friz Quadrata vs Ka0s Prototype), a probe logging every aura, and
5 fps video frames showed the aura data always carried the name and only the
addon font blanked. Drawing the fonts early on a shown frame removed every
blank, also on master without the repaint. The findings get a correction
section; a new design replaces NameRepaint with a font primer.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit e38768a13014980185947d6ffd49dd15b355a665
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 16:43:23 2026 +0530
NR-07: final checkpoint
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit a4261d742a0fdb5584299b9623dc6426f2612bd1
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 16:40:19 2026 +0530
NR-06: address review: the pass times only the mark, honest allocation and latency bounds, runnable BN checks
UpdateAllAuras on a managed container only marks it dirty for a full
rebuild and refreshes its enchants; the engine rebuilds in the container's
next OnUpdate (Blizzard_ManagedAuraContainer.lua UpdateAllAuras, OnUpdate,
OnDirtyChanged). So the nameRepaint bucket never held the rebuild:
- performance.md (pass cost, bucket row, reading a capture), the NameRepaint
header and the PerfSetup bucket comment now say the bucket times the mark
and the rebuild lands in no addon bucket.
- BN8 no longer reads nameRepaint maxMs as a cost. It takes a second capture
with #1's name hidden (so the repaint neither listens nor runs) and judges
the rebuild from the frame-time arms.
- New BN9: whether a Text line's pulse or bounce snaps when a repaint
reassigns buttons.
Also:
- The PerfSetup bound now matches performance.md: one pass per 2 s under
constant churn, at most two per 2.5 s in bursts.
- Allocation claims narrowed: an event on an armed unit allocates nothing,
arming allocates one timer handle. probeAbsent's Arm returns at the
listened check in the runner, so it proves only that early return is free
(perf.lua, performance.md).
- Latency per case in known-limitations (about 2.5 s quiet, about 4 s while
already changing, 3 s / 5 s after a loading screen), debug.md and
midnight-quirks (within about 2 s, or 3 s just after a loading screen).
- BN1 checks passes and last= in /am diagnostics, since the trace is off at
login; BN3 turns the trace on after login; BN4 waits for each swap's
(settle) line before the next.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 71c34327ba661ea26f4bb28f4a501de00b41b846
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 16:37:17 2026 +0530
NR-06: address review: pin the focus swap, the QUICK-window dirty clear, the parked gate and a refused registration
Four mutations the suite let through now fail a case each:
- OnUnitSwap arming target on a focus swap: a focus swap must arm focus:quick
alone and repaint only the focus container.
- onFirst keeping the QUICK-window dirty mark: the burst test now runs QUICK
and SETTLE and expects nothing rearmed.
- eligible() without its parked gate: a parked container whose ShouldShow is
stubbed to answer yes must still be skipped. The combined case's red-under
note now names staleData only, since ShouldShow already refuses parked.
- setFrame storing the wanted units whatever the registration answered: a
refused RegisterUnitEvent must leave the unit unheard, unarmed and out of
the report, record UNIT_AURA once, and let the next Sync retry.
test-cases.md regenerated and the badge moved to 1705/1705.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 0c83e8074948271b7968d4cfcd47cb955f19bcbd
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 16:23:57 2026 +0530
NR-CP-M2: M2 checkpoint
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit a1416edb4884de264c710c9d5e3815c936f16acb
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 16:22:23 2026 +0530
NR-05: address review: restate the repaint rate bound, restyle vs reread, swap timing, refused-UNIT_AURA coverage
The timers bound a unit to one pass every 2 s only under constant churn;
bursty churn allows two passes per 2.5 s (about 0.8/s, as little as 0.5 s
apart). debug.md, performance.md (overview, timer paragraph, cost section,
bucket row) and BN8 now state that bound; a swap takes the same Arm path,
so it adds nothing to it. debug.md separates the toggles (SetEnabled flip,
UpdateAllAuras reread) from a restyle (apply rerun with stored aura data).
A swap while a timer is armed is repainted at the armed follow-up, not
0.5 s later. midnight-quirks.md lists EmptyWatch's and NameRepaint's unit
frames among the safe registrations and adds their refused-UNIT_AURA trades.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 5587eb6ac5ce1fec745977fdae7969aad5496047
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 16:17:23 2026 +0530
NR-05: Docs for the blank bar name repaint
debug.md rewrites "Bar names that do not show" around the real cause and
adds the [Names] trace and the no-toggle rule. midnight-quirks.md gains the
measured 2026-09-27 section (the name is written on assign or update only,
a blank first sighting persists, UpdateAllAuras rereads, SetEnabled flips
repaint by accident) and cross-references it from the unit-swap section.
ARCHITECTURE.md: the NameRepaint event row, the swap and world-entry rows,
the unit-frame census, 54 files / 18 modules, and the aura-path overview.
data-flow.md: lifecycle rows, the stand-down row and a repaint section.
module-map.md: eight buckets, ShowsEngineName, the nameRepaint bucket.
performance.md: the nameRepaint bucket row, its cost subsection, the two
offline scenarios, and every "no aura-driven path in combat" claim fixed.
known-limitations.md and a README Troubleshooting row for the blank window.
smoke-tests.md: checks 281-288 (BN1-BN8), results left for the owner.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 12102a0c0eab55fe2a9dddefb8cca50087773b5c
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 16:08:35 2026 +0530
NR-04: address review: make the read-only case catch a syncing report; qualify the passes/last triage
The read-only diagnostics case now changes the target container to bars without running its
visibility pass, so a report that calls NR.Sync opens the target frame and fails the case (checked
by adding NR.Sync() to NR.DiagState: 1 failure). Its red-under note names both mutations.
debug.md no longer says a climbing passes= with a recent last= rules the cause out: both are
session-wide and a pass counts even when it reaches no container.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit c0ab988245360d40641ad57c0534227d1c860538
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 16:04:14 2026 +0530
NR-04: Diagnostics: the name repaint header line replaces the cee5bb6 width fields
Spec D6. The cee5bb6 fields rested on a refuted hypothesis (a time box squeezing the name out) and
read `?` on every live bar, so they go: the nameW=/timeW=/barW= suffix on bars [Shown] lines, the
"time-text widths cached" header line and Style.MeasuredTimeWidths.
In their place one header line from the repaint's own state:
name repaint: listening=<units|none> armed=<unit:stage,...|none> passes=<n> last=<unit>@<time>|never
- modules/NameRepaint.lua: a pass counter and the last pass's unit and GetTime, kept in scalars by
NR.Repaint (the event and repaint paths still allocate nothing; tests/perf.lua unchanged), and
NR.DiagState, a read-only snapshot: it registers nothing, arms nothing and holds nothing, so it
answers while stood down (debug-logging-§14).
- modules/Diagnostics.lua: repaintLine in place of measuresLine; the probe loses barWidths. The
last time is formatted only once Secrets.IsReadableNumber passes.
- tests/test_diagnostics.lua: the four width cases replaced by five: the fields are gone, the
listened units, the armed stages with the pass count and last pass, no registration or timer
from the report, and the line while auras are secret and while stood down.
- docs/debug.md: the Diag and Shown rows, the example block, and "Bar names that do not show"
rewritten around the real cause and the new line.
- docs/test-cases.md regenerated and the README badge moved (1701 -> 1702).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit de47c8f924a39dce16e1fb83b1c9037275f7f252
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 15:58:30 2026 +0530
NR-CP-M1: M1 checkpoint
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit de554d12df9ff6d464ac2faf44b4d3e28bb2fad8
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 15:56:28 2026 +0530
NR-03: address review: count all three one-shots in the stand-down red-under note
The 'red under' note in test_disabled still said 'both' after NR-03 raised
the armed one-shots to three (apply, scan and the repaint's QUICK).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 39b41b88e4b16766ac4e7c0afdb0147f46b657ed
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 15:52:26 2026 +0530
NR-03: Wire the blank-name repaint: Sync, world entry, unit swaps, stand-down, perf bucket
- CM.FlushPending and CM.ApplyVisibility end in NameRepaint.Sync, next to EmptyWatch.Sync.
- addon:OnEnterWorld calls NameRepaint.OnEnterWorld; OnUnitSwap and OnUnitPet arm the swapped unit
after CM.RefreshUnit.
- standDown calls NameRepaint.Stop next to EmptyWatch.Stop; standUp is unchanged.
- The nameRepaint perf bucket, declared last in core/PerfSetup.lua and bracketed Shape A around
NR.Repaint; the descriptor comment now counts three aura-driven paths.
- tests/perf.lua: a nameRepaint scenario (one timer per unit, 0 B per event once armed, one
UpdateAllAuras per eligible container); probeAbsent leaves Sync and Arm out, so they add 0 B.
- test_perf (8 buckets, BUCKET_ORDER, exercise() drives a real pass), test_disabled (the extra
player row and the QUICK timer) and test_emptywatch (counts EmptyWatch's timer only), each with a
comment; eight wiring cases in test_namerepaint.
- Doc citations re-cited; test-cases.md regenerated; badge 1701/1701.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 95dcd2724cfe2426f056f78ccec5b4d465c05c09
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 15:42:54 2026 +0530
NR-02: address review: prove the stand-down gates in Arm, OnEnterWorld and the timer callbacks
The stood-down case only reached Arm and OnEnterWorld after Stop had released the frames, so
listened() returned early and neither gate was ever exercised. A new case stubs the stand-down
latch with the frames still held; a second fires an armed QUICK and a dirty SETTLE after the
latch flips and asserts no repaint and no rearm. The Stop case's note named a dirty mark that
onFirst always clears; it now names the mutation it catches (a canceled timer's handle kept),
and cancel() says its dirty clearing is defensive. Each gate's removal was confirmed red.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 3e6f316b169109a02c13793e565abf2f1fc66003
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 15:35:51 2026 +0530
NR-02: modules/NameRepaint.lua, the blank bar name repaint: listening, two-stage timers, the pass
Two hidden UNIT_AURA unit-filter frames (player/pet, target/focus) registered only for units with
an enabled container that shows an engine-written name (Style.ShowsEngineName), open in combat and
while auras are secret, the handler bounding its unit through IsSafeKey. Per unit, QUICK 0.5 s then
SETTLE 2 s (rearmed only while dirty), ENTER 3 s from OnEnterWorld, prebuilt callbacks. Repaint
sends UpdateAllAuras to every shown, live, non-previewing, name-showing container on the unit, with
one Names trace line per pass. Sync is idempotent, allocation-free and stops while stood down.
Not yet wired into ContainerManager or the lifecycle (NR-03).
TOC entry after ContainerManager with its Conventional note; module-map rows; 18 new cases in
tests/test_namerepaint.lua; test-cases.md regenerated and the badge at 1691.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 2a67d2e28395491027d26e55cc3292815b5779c7
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 15:26:51 2026 +0530
NR-01: address review: shared refusal for a non-string template, test-cases.md regenerated
TT.Compile built a fresh { ok = false } table on every call for a template
that is not a string, so Style.ShowsEngineName allocated on a container with
no text block despite its allocation-free claim. The refusal is now one
shared table, like the cached refusals of string templates.
docs/test-cases.md is regenerated with test_namerepaint.lua tracked, which
moves the tracked-file count in one case name from 181 to 182.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit f50bba7918d671958735b688d125576baf020f9b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 15:23:04 2026 +0530
NR-01: Style.ShowsEngineName, the predicate for which containers show an engine-written name
Added at the end of modules/Style.lua (spec D2) so no documented line
citation moves. Bars (Style.StyleKey's answer) show a name unless
bars.name.show is false; text shows one when the compiled template it
draws (Text.Compiled, so a refused template answers for the default) has
a name piece; icons never. Allocation-free.
New suite tests/test_namerepaint.lua with the eight predicate cases,
declared in tests/run.lua and listed in docs/module-map.md;
docs/test-cases.md regenerated and the README badge at 1673/1673.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit f3deec511da3f250eff72c13bcaad3e72fd6a66d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 15:20:18 2026 +0530
NR-00: Spec, findings and resumable plan for the blank bar names fix (#24)
The aura engine writes a bar's name from auraData.name only on assign or
update, so a name missing on first sighting stays blank for the aura's life.
The spec adds a rate-bounded UpdateAllAuras repaint of name-showing
containers after their unit's auras change, after unit swaps and after
loading screens. Folds in an adversarial spec review (9 confirmed points).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012HEXhbALx2TeHBKfc4jhZj
commit 8ef48d2280752bf62df437ce33b50d0079127a41
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 12:26:42 2026 +0530
Minor edist to screenshots and README
commit f637a59e1176e785900b1e526b71cdcc37c040da
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 03:31:27 2026 +0530
README: refresh the in-combat screenshot
A new capture of the live-in-combat screenshot (01, both the JPEG and the PNG original), and the
README's first screenshot now links its new CurseForge upload.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
This mod has no additional files

