promotional bannermobile promotional banner

Ka0s Aura Master

Build your own buff, debuff and weapon enchant displays for player, target, focus and pet, as bars or icons.
Back to Files

1.0.1-release

File nameAuraMaster-1.0.1-release.zip
Uploaded
Sep 27, 2026
Downloads
16
Size
32.0 MB
Flavors
Retail
File ID
8992009
Type
R
Release
Supported game versions
  • 12.1.0

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