promotional bannermobile promotional banner

Ka0s Absorb Tracker

Display your total absorb shield value in a clean, customizable bar interface.
Back to Files

1.11.0-release

File nameAbsorbTracker-1.11.0-release.zip
Uploaded
Sep 26, 2026
Downloads
222
Size
6.6 MB
Flavors
Retail
File ID
8985131
Type
R
Release
Supported game versions
  • 12.1.0

What's new

commit 3b7e1fd395f3a46a7dc78418da9854b390a07ac3
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Sep 27 03:07:50 2026 +0530

    Release 1.11.0: version bump, release notes and the gated release run

    Release gate (docs/automated-tests/20260927-030336/manifest.json, run with
    --release 1.11.0 on 9b5a369, clean tree), all five conditions PASS:
    - Lint: pass, 0 warnings / 0 errors in 67 files
    - Tests: pass, 810 passed, 0 failed, 0 skipped of 810
    - Perf: pass, 6 scenarios from tests/perf.lua
    - Complexity: pass, 13377 NLOC / 1919 functions, avg CCN 1.7
    - CCN <= 15: 0 warnings, max CCN 14

    Files changed:
    - AbsorbTracker.toc: ## Version 1.10.0 -> 1.11.0
    - core/Namespace.lua: NS.version "1.10.0" -> "1.11.0"
    - docs/module-map.md, docs/slash-dispatch.md, docs/smoke-tests.md:
      version mentions rolled to 1.11.0
    - README.md: new 1.11.0 row at the top of ## Version History
    - docs/automated-tests/20260927-030336/: the release bundle, with its
      ANALYSIS.md
    - docs/automated-tests/RESULTS.md: the release row and refreshed watch-list
      dispositions

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit 9b5a369a95fe9a9bc8eb0fdc1ad448d75d55b8e2
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Sep 27 03:03:28 2026 +0530

    README: Usage as the primary setup flow, and sync-docs

    - Usage restructured around the four-step setup flow.
    - How the bar works now opens on UnitGetTotalAbsorbs and secret values.
    - sync-docs fixes in DEPENDENCIES.md and the ARCHITECTURE documentation map.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit b2b4bb72ba5bd6eb002f2b6dbbc53bacf5fbc705
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Sep 27 02:28:21 2026 +0530

    README: credit the third-party font and icons the addon ships

    Credits now names the debug console's JetBrains Mono (SIL OFL 1.1) and the Open Iconic ? and X on the bar's drag handle (MIT). Both ship inside the vendored LibKa0s payload with their license text,
    and documentation-§1 item 12 keeps Credits for exactly this kind of external asset (a font, an icon
    set), never a library list.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit fc1a82d6c144d0dfea055ca4397f50543f60309e
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Sep 27 00:15:29 2026 +0530

    README: plain-language pass for readers

    Rewrote the prose for the person reading it: long run-on paragraphs split by topic, em dashes
    and reflexive bold removed, passive and subjectless sentences given someone doing the action,
    and sentence length varied. Every fact, command, setting name, link, badge, heading and the
    section order are unchanged, as is every section a test or the tooling cites verbatim.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit 4a1178f5fb5659f37c872064b069a9bbf94f7348
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 23:06:49 2026 +0530

    AT-ATS-SDR: Repoint the Sl colon-call citation in .luacheckrc to core/AbsorbTracker.lua:52

    Review finding on 917014b: line 44 is blank; NS.Slash:Register() is at :52. Comment-only.
    Gate: 810/0/0, luacheck 0/0 in 67 files.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit 4a1178f5fb5659f37c872064b069a9bbf94f7348
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 23:06:49 2026 +0530

    AT-ATS-SDR: Repoint the Sl colon-call citation in .luacheckrc to core/AbsorbTracker.lua:52

    Review finding on 917014b: line 44 is blank; NS.Slash:Register() is at :52. Comment-only.
    Gate: 810/0/0, luacheck 0/0 in 67 files.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit 917014b15fc38c45578c58a55dc9cf4a24b80dd2
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 23:02:59 2026 +0530

    AT-ATS-SDR: Correct stale comment citations (owner-approved sync-docs follow-up)

    - .luacheckrc:118 - degraded-arm stub `SlashLib:New(d)` is at settings/Slash.lua:603 (was :410)
    - .luacheckrc:120 - `function lib:New(d)` is at libs/LibKa0s/Slash.lua:484 after the v1.62.0
      re-vendor (was :375)
    - .luacheckrc:120 - `SlashLib:New({...})` call is at settings/Slash.lua:661 (was :448)

    Comment-only; no code change.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit 58c04ec625fe46150d185568fe4483cc48f0f119
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 19:44:25 2026 +0530

    AT-ATS-SD: Sync docs to the tree after the automated-tests sweep

    - docs/module-map.md: the harness paragraph's suite list now matches
      tests/run.lua's ordered list. It gains test_draghandle, test_events and
      test_diagnostics, and names all four kit suites (test_prose,
      test_diagnostics_contract, test_eol, test_layout_cap) instead of test_eol
      alone.
    - docs/scope.md: the same suite list gains test_events and test_diagnostics
      and the three kit suites it left out.
    - docs/automated-tests/RESULTS.md: "neighbour" -> "neighbor" in the
      test_widgets.lua Disposition prose (localization-§5). The kit's prose gate
      was red on it at 0479a09 (809/1/810). No number in the record changed.

    Green gate after: lua tests/run.lua 810/0/810, luacheck 0/0 in 67 files,
    docs/test-cases.md matches `lua tests/run.lua --list`.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit 0479a0906dd3394b1b51e75af9f2401a7ef15c74
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 19:33:01 2026 +0530

    AT-ATS-99: Final automated-tests sweep run (20260926-193105)

    Closing run of the 2026-09-26 automated-tests sweep, measured at fb55f44 on a
    clean tree. Verdict green.

    - lint: pass, 0 warnings / 0 errors in 67 files (66 at 20260926-160433; the
      new tests/test_panelpages.lua)
    - tests: pass, 810/0/810 (unchanged; AT-ATS-01 moved 71 cases verbatim,
      now 40 in test_helpers + 31 in test_panelpages)
    - perf: pass, 6 scenarios, api/iter and bytes/iter identical in every one
    - complexity: pass, 13377 NLOC (13366), 1919 functions (1920), avg NLOC 6.4,
      avg CCN 1.7, max CCN 14, avg tokens 46.5, 0 warnings; band 3 -> 2 files,
      0 over cap

    What moved vs 20260926-160433: tests/test_helpers.lua left the 1000-1500
    band (1447 -> 573 lines) after the AT-ATS-01 peel; test_ltrap.lua lost one
    function with the LibKa0s v1.62.0 re-vendor. Nothing newly crossed.
    RESULTS.md: refreshed the carried Disposition cells for test_slashcmds.lua
    (1321) and test_widgets.lua (1073) to cite this run; rulings unchanged.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit fb55f4407efb01275711c0cdb8281e422e5a3900
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 18:57:44 2026 +0530

    AT-ATS-01: Peel the rendered-page cases out of test_helpers into test_panelpages

    tests/test_helpers.lua was 1447 lines, 53 short of the layout-cap. Its
    rendered-page cases now live in a new tests/test_panelpages.lua. They cover
    the per-unit Appearance page from settings/UnitPanel.lua (Unit picker,
    chrome block, mirror controls, tab strip, the two-tier refresher), the
    General page's Reset position button, and /at resetposition beside it. The
    split follows the file's existing "The Appearance page" section boundary,
    and no moved case reaches into a local defined above it. The cases moved
    verbatim and in their original order. The runner loads the new suite
    straight after test_helpers because its first case asserts that the
    Appearance page has not rendered yet. The L-trap case stays in test_helpers
    beside the library contract it pins.

    - tests/test_helpers.lua: 1447 -> 573 lines, 71 -> 40 cases
    - tests/test_panelpages.lua: new, 894 lines, 31 cases
    - Suite total 810 before and 810 after, the same set of case names
      (sorted PASS lines compared). docs/test-cases.md was regenerated.
    - Comments and docs that pointed at test_helpers for the moved cases now
      point at test_panelpages. The module-map, common-tasks and scope suite
      lists, the ARCHITECTURE layout census (largest authored file is now
      test_slashcmds at 1321) and the RESULTS.md watch-list row are updated.

    Gate: 810 passed / 0 failed; lint 0 warnings / 0 errors in 67 files;
    complexity 0 warnings; inventory in sync; no authored file over 1500 lines.

    Traces: ATS-11, review finding AbsorbTracker-R-14.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit 0aceec73619c37ce9b28b5692bc9087a78fcb877
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 18:50:13 2026 +0530

    AT-ATS-RVR: Roll the module-map census rows for the LibKa0s v1.62.0 re-vendor

    Brings docs/module-map.md in line with what AT-ATS-RV vendored:
    - tests/_kit/ row: kit revision 31, 10271 lines, framework.lua 984 and
      test_prose.lua 750, and names the new inventory.lua, prose_coverage.lua
      and prose_selftests.lua.
    - tests/test_ltrap.lua row: 252 lines, and the Options tripwire reads every
      Options*.lua off LibKa0s.xml (ten files) rather than three.
    - The Options section prose, the settings/ intro and the
      settings/OptionsSetup.lua row list the ten Options files; OptionsSetup is
      383 lines.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit 5042c6b487be0f596f79778dfff52a543694243f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 18:46:22 2026 +0530

    AT-ATS-RV: Re-vendor LibKa0s v1.62.0 and read the Options tripwire off the XML

    LibKa0s payload from the local v1.62.0 tag (ATS-20, ATS-21): Options 25 -> 26, OptionsWidgets
    31 -> 32, OptionsTabs 5 -> 6, and four new files at minor 1 (OptionsRegistry, OptionsIds,
    OptionsIdList, OptionsCombat); Options key 26.1.32.1.1.6.1.7.4.1. tests/_kit moves from kit
    revision 27 to 31, which carries the None. line under an empty complexity watch-list table (ATS-20)
    and the generated-file carve-out in the band table (ATS-21). CLAUDE.md provenance and
    docs/testing.md's version-now line roll with it.

    No member, descriptor field or row field changed, so the library-absent stub needs no new member;
    its comment now names the id members' new home. tests/test_ltrap.lua's Options tripwire read a
    hand-typed list of three files, which the code peeled into OptionsIds, OptionsIdList and
    OptionsRegistry would have left unseen; it now reads every Options*.lua off the vendored
    LibKa0s.xml (ten files), same case. The library census in module-map, ARCHITECTURE and performance
    moves to twenty-seven files with the new load order. docs/test-cases.md regenerated, unchanged.
    Bundle docs/revendor/2026-09-26-v1.62.0; no adoption in this item.

    Gate: 810 passed, 0 failed (810 before); 0 warnings / 0 errors in 66 files; no function above
    CCN 15.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit 7f4fa5ac9f9db0fed84435ce21fa53eef2db8c8d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 16:19:00 2026 +0530

    AT-ATS-00: Record the 2026-09-26 automated-tests sweep run (20260926-160433)

    The collection-wide sweep's bundle and RESULTS.md, as the sweep left them. The fix queue it
    produced is Ka0sAddonsCommonTasks docs/2026-09-26-AUTOMATED_TESTS_SWEEP.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit 1c27f7a175f96edd7d373d2f829d121ed8d5dde3
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 14:44:12 2026 +0530

    NR-AT-01: Re-vendor LibKa0s v1.61.0 and stub NavRail

    LibKa0s payload from the v1.61.0 tag: Options 24 -> 25, OptionsTabs 4 -> 5, the new OptionsNav minor 1 (Options key 25.31.5.7.4.1). tests/_kit is unchanged at kit revision 27, so it is not copied. CLAUDE.md provenance and docs/testing.md's version-now line roll with it. The library-absent stub gains a NavRail no-op for the Options surface-parity case; no page here draws a rail.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit 1c27f7a175f96edd7d373d2f829d121ed8d5dde3
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 14:44:12 2026 +0530

    NR-AT-01: Re-vendor LibKa0s v1.61.0 and stub NavRail

    LibKa0s payload from the v1.61.0 tag: Options 24 -> 25, OptionsTabs 4 -> 5, the new OptionsNav minor 1 (Options key 25.31.5.7.4.1). tests/_kit is unchanged at kit revision 27, so it is not copied. CLAUDE.md provenance and docs/testing.md's version-now line roll with it. The library-absent stub gains a NavRail no-op for the Options surface-parity case; no page here draws a rail.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit 13f1e23525372e6a1c796bb82264accef10f0f74
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 09:32:09 2026 +0530

    DR-AT-07: Standards refresh to v2.68.0, docs synced, AUD-01 self-check passes

    The M4 item of the diagnostics rollout: the revendor-standards sweep
    against WowAddonStandards v2.68.0 (local master 2854053), a sync-docs
    pass and the AUD-01 self-check, done by hand in this repo only.

    revendor-standards: nothing to change.
    - Three-place reference intact: AbsorbTracker.toc:12 X-Standard carries
      the repo URL; the README badge (README.md:6) is the bare, unlinked
      image with _ not %20; CLAUDE.md "Standards compliance (read first)"
      keeps stop-and-flag and the two-way classification. No version stamp.
    - Retired notation: grep -rEn '§[0-9]+\.[0-9]' . (libs, _kit, audits,
      reviews, automated-tests excluded) -> 0 hits.
    - 77 distinct filename-§N citations range-checked against the section
      files' own "### N." headings: 0 out of range, 0 unknown files
      (debug-logging has 14 sections, so the new §14 citations resolve).
    - The one documentation-§1 item citation (item 9, test_docs.lua:75 and
      module-map.md:902) already names the new Reporting a bug item.
    - Retired names (complexity.md, agent-context.md) appear only as
      retired; the one "drop-in" hit (settings-panel.md:379) is about AGSMW.
    - testing.md and automated-tests/README.md name both checkpoints.
    - .gitattributes pins CRLF with the *.sh/*.py carve-outs; every edited
      file keeps CRLF (CR count equals LF count).

    sync-docs: one AUD-01 gap and three drifts, all closed here.
    - AUD-01 step 3 reads "tests/test_disabled.lua dispatches both forms".
      Its step-7 walk sent `diagnostics` bare but never `debug diagnostics`
      (only the kit's shared contract case did). test_disabled.lua gains
      "disabled 7: both diagnostics forms reach RunDiagnostics, each once,
      with no refusal". It is a characterization case, since the route
      already worked. Falsified by renaming runDebug's `diagnostics` branch
      (settings/Slash.lua:367): the new case went red (with the contract
      and diagnostics cases), then the file was restored.
    - docs/test-cases.md regenerated (809 -> 810); README badge 810/810.
      The README change is the badge number only, so the de-AI pass had no
      prose to review.
    - docs/module-map.md: test_disabled.lua's line count (608 -> 633) and
      its step-7 summary name the new case; docs/common-tasks.md's suite row
      says the same.
    - docs/ARCHITECTURE.md's core/DebugLogSetup.lua row did not mention the
      diagnostics descriptor fields or the stub's RunDiagnostics; it now
      names `brandName`, the call-time `diagnostics` hook and the stub's
      library-absent line (module-map.md already did).
    - Checked and unchanged: NS.COMMANDS has 19 rows and ARCHITECTURE says
      nineteen verbs; the Documentation map both ways (compat-layer.md is
      Not applicable and absent, debug.md Present); every module-map line
      count; kit revision 27 (Kit.VERSION); fifteen majors across
      twenty-two files; the v1.60.0 provenance line.

    AUD-01 (02_SPEC.md), run by hand on this commit, all steps pass
    1. grep '"diagnostics"' settings/*.lua core/*.lua: one COMMANDS row
       (settings/Slash.lua:119); runDebug tests `diagnostics` before every
       other word (Slash.lua:367). The third hit is the stub's DebugVerb
       (core/DebugLogSetup.lua:79), not a COMMANDS row.
    2. grep -rniE '"(diag|dump|dx)"' settings core modules: empty.
    3. liveVerbs is built on SlashLib.LIVE_VERBS plus resetposition and
       profile (Slash.lua:699-704); test_disabled.lua now dispatches both
       forms while disabled.
    4. Both forms call NS.DebugLog:RunDiagnostics (Slash.lua:356); no
       :Clear in modules/Diagnostics.lua.
    5. The stub's RunDiagnostics prints the library-absent line and writes
       nothing (core/DebugLogSetup.lua:34-39, :71).
    6. README ## Reporting a bug (README.md:137) sits between
       Troubleshooting and Issues and feature requests, with the three steps
       and the note verbatim for /at, no destination and no link.
    Result: AUD-01 passes (vendor v1.60.0, so no #47/#90).

    Gate: lua tests/run.lua 810 passed, 0 failed; luacheck 0 warnings / 0
    errors in 66 files; lizard -C 15 -w clean (libs and tests/_kit
    excluded); largest Lua file 1447 lines.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit 13f1e23525372e6a1c796bb82264accef10f0f74
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 09:32:09 2026 +0530

    DR-AT-07: Standards refresh to v2.68.0, docs synced, AUD-01 self-check passes

    The M4 item of the diagnostics rollout: the revendor-standards sweep
    against WowAddonStandards v2.68.0 (local master 2854053), a sync-docs
    pass and the AUD-01 self-check, done by hand in this repo only.

    revendor-standards: nothing to change.
    - Three-place reference intact: AbsorbTracker.toc:12 X-Standard carries
      the repo URL; the README badge (README.md:6) is the bare, unlinked
      image with _ not %20; CLAUDE.md "Standards compliance (read first)"
      keeps stop-and-flag and the two-way classification. No version stamp.
    - Retired notation: grep -rEn '§[0-9]+\.[0-9]' . (libs, _kit, audits,
      reviews, automated-tests excluded) -> 0 hits.
    - 77 distinct filename-§N citations range-checked against the section
      files' own "### N." headings: 0 out of range, 0 unknown files
      (debug-logging has 14 sections, so the new §14 citations resolve).
    - The one documentation-§1 item citation (item 9, test_docs.lua:75 and
      module-map.md:902) already names the new Reporting a bug item.
    - Retired names (complexity.md, agent-context.md) appear only as
      retired; the one "drop-in" hit (settings-panel.md:379) is about AGSMW.
    - testing.md and automated-tests/README.md name both checkpoints.
    - .gitattributes pins CRLF with the *.sh/*.py carve-outs; every edited
      file keeps CRLF (CR count equals LF count).

    sync-docs: one AUD-01 gap and three drifts, all closed here.
    - AUD-01 step 3 reads "tests/test_disabled.lua dispatches both forms".
      Its step-7 walk sent `diagnostics` bare but never `debug diagnostics`
      (only the kit's shared contract case did). test_disabled.lua gains
      "disabled 7: both diagnostics forms reach RunDiagnostics, each once,
      with no refusal". It is a characterization case, since the route
      already worked. Falsified by renaming runDebug's `diagnostics` branch
      (settings/Slash.lua:367): the new case went red (with the contract
      and diagnostics cases), then the file was restored.
    - docs/test-cases.md regenerated (809 -> 810); README badge 810/810.
      The README change is the badge number only, so the de-AI pass had no
      prose to review.
    - docs/module-map.md: test_disabled.lua's line count (608 -> 633) and
      its step-7 summary name the new case; docs/common-tasks.md's suite row
      says the same.
    - docs/ARCHITECTURE.md's core/DebugLogSetup.lua row did not mention the
      diagnostics descriptor fields or the stub's RunDiagnostics; it now
      names `brandName`, the call-time `diagnostics` hook and the stub's
      library-absent line (module-map.md already did).
    - Checked and unchanged: NS.COMMANDS has 19 rows and ARCHITECTURE says
      nineteen verbs; the Documentation map both ways (compat-layer.md is
      Not applicable and absent, debug.md Present); every module-map line
      count; kit revision 27 (Kit.VERSION); fifteen majors across
      twenty-two files; the v1.60.0 provenance line.

    AUD-01 (02_SPEC.md), run by hand on this commit, all steps pass
    1. grep '"diagnostics"' settings/*.lua core/*.lua: one COMMANDS row
       (settings/Slash.lua:119); runDebug tests `diagnostics` before every
       other word (Slash.lua:367). The third hit is the stub's DebugVerb
       (core/DebugLogSetup.lua:79), not a COMMANDS row.
    2. grep -rniE '"(diag|dump|dx)"' settings core modules: empty.
    3. liveVerbs is built on SlashLib.LIVE_VERBS plus resetposition and
       profile (Slash.lua:699-704); test_disabled.lua now dispatches both
       forms while disabled.
    4. Both forms call NS.DebugLog:RunDiagnostics (Slash.lua:356); no
       :Clear in modules/Diagnostics.lua.
    5. The stub's RunDiagnostics prints the library-absent line and writes
       nothing (core/DebugLogSetup.lua:34-39, :71).
    6. README ## Reporting a bug (README.md:137) sits between
       Troubleshooting and Issues and feature requests, with the three steps
       and the note verbatim for /at, no destination and no link.
    Result: AUD-01 passes (vendor v1.60.0, so no #47/#90).

    Gate: lua tests/run.lua 810 passed, 0 failed; luacheck 0 warnings / 0
    errors in 66 files; lizard -C 15 -w clean (libs and tests/_kit
    excluded); largest Lua file 1447 lines.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit d15ba41ec33f773fabf1a9cf081acf4d750d1811
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 09:25:39 2026 +0530

    DR-AT-06R: Rewrap the enUS header comment DR-AT-06 left at 125 columns

    DR-AT-06 rewrote the "What IS routed" paragraph at the head of
    locales/enUS.lua but left one line at 125 columns, where the rest of
    the file wraps at 100. Comment-only reflow; the words are unchanged and
    the file stays at 73 lines, so module-map.md's count still holds.

    Gate: lua tests/run.lua 809 passed, 0 failed, 0 skipped; luacheck 0
    warnings / 0 errors in 66 files; lizard -C 15 -w clean (libs and
    tests/_kit excluded); no authored Lua file over 1500 lines.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit d1cbdfb62a271a93f05e4446704441e9962ff801
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 09:23:08 2026 +0530

    DR-AT-06: Put a close mark (X) on every bar's drag strip, the player bar included

    The owner's ruling (DR-OW-03, X-04): AbsorbTracker adopts
    LibKa0s-Widgets-1.0's DragHandle close mark on every strip, player,
    target and focus, with no player-bar exception.

    modules/Bar.lua hands each DragHandle an onClose, the `close` icon from
    the Media seam and its own closeTooltip. A click runs closeBar(unit),
    which writes the existing row `units.<unit>.enabled = false` through
    NS.SetByPath, the same row General > Bars draws and `/at toggle <unit>`
    flips. Its onChange therefore re-syncs the unit's event registrations
    and the [Set] trace, the bus and an open panel fire as they do from the
    checkbox. It never touches the addon-wide `enabled`, the shared `locked`
    or the bar's position, so turning the bar back on puts it where it was.
    One chat line names the way back ("Target bar hidden. Re-enable it on
    General > Bars or with /at toggle target."), and the X's tooltip carries
    the same sentence. No combat rule of its own: the strip only shows
    unlocked, and the lock closes in combat. Four new locale keys, ASCII.

    Tests (X-05), test_draghandle.lua 22 -> 29, written first and seen
    failing (7 failed): the X is present on all three strips with art; the
    spec's closeIcon is NS.Icon("close"); Reserve() is RESERVE + HELP_HIT +
    CLOSE_GAP on every strip; a click writes exactly the one row through
    the seam; position, the other bars and the addon-wide enable are left
    alone; the chat line; the X's tooltip. Measure pins re-checked: the
    narrow-bar case (test_draghandle.lua:182) compares ApplyWidth against
    handle:Measure() rather than a literal, so it absorbs the 36px the X
    adds and needed no change; no other test pins a strip width.

    Docs: README usage paragraph (the X and the way back) and test badge
    809; test-cases.md; module-map.md (the handle paragraph, the Bar,
    enUS, MediaSetup and test_draghandle rows and line counts);
    ARCHITECTURE.md and common-tasks.md rows; smoke-tests.md item 68(a)
    and new item 68b (S6); the MediaSetup and enUS comments naming what
    reads them.

    Gate: lua tests/run.lua 809 passed, 0 failed, 0 skipped; luacheck 0
    warnings / 0 errors in 66 files; lizard -C 15 -w clean (libs and
    tests/_kit excluded); no authored Lua file over 1500 lines.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit 9f6d52e4e51dd6e225eb676805c0c0d6a70557b5
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 09:18:21 2026 +0530

    DR-AT-05R: debug.md's trace-tag table names every tag the console gets

    Independent review of DR-AT-05. The new docs/debug.md says the trace
    tags table lists the tags NS.Debug writes, but it left out two tags and
    understated two others:

    - `[Set]` said "one line per bulk copy or reset". LibKa0s-Schema-1.0's
      logWrite also writes one `path = value` line for every single setting
      write (libs/LibKa0s/Schema.lua:479), and core/AbsorbTracker.lua writes
      `[Set]` for a profile copied or reset (:380-:388).
    - `[Profile]` was missing: core/AbsorbTracker.lua:369 logs a profile
      change.
    - `[Launcher]` named only core/LauncherSetup.lua. LibKa0s-Launcher-1.0
      logs through the same descriptor sink (Launcher.lua:239).
    - `[Cfg]` was missing: LibKa0s-Options-1.0 logs the panel opening and a
      register or open held back in combat (Options.lua:1319/:1393/:1399).

    Everything else in the commit was checked against the code and holds:
    the thirteen sections, their order and tags, the stood-down wording,
    the caps (min(1200, 3000 - 100), 40 per list, 200-char wrap, two lines
    reserved), the library-absent line, the chat line, the one-key L table,
    the smoke section V steps, and no alias. The TDD red was reproduced in a
    scratch worktree: with the old ARCHITECTURE.md row, "every Tier 2
    documentation-map row agrees with docs/" fails.

    Documentation only; the file stays CRLF.

    Gate: lua tests/run.lua 802 passed, 0 failed, 0 skipped; luacheck 0
    warnings / 0 errors in 66 files; lizard -C 15 -w clean (libs and
    tests/_kit excluded); largest authored Lua file 1447 lines.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit 0ddccec46ebbb1619ea43429d0cb286c2542e274
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 09:14:48 2026 +0530

    DR-AT-05: docs/debug.md documents /at diagnostics; the Tier-2 row flips to Present

    debug-logging-§14 "Documented" and documentation-§3's Tier-2 trigger
    (standard v2.68.0, STD-20, STD-23): the diagnostics report is a debug
    surface of the addon's own, so docs/debug.md now exists.

    - docs/debug.md (new): both forms and no alias (`debug diag` toggles the
      console, `/at diag` is unknown), the raw-append rule (ungated, flag
      untouched, answers while disabled; `debug hold` is the one word that
      refuses), the library-absent line, the one localized chat line, the
      report's shape (library frame, then the thirteen sections of
      modules/Diagnostics.lua in order with their tags and contents), the
      stood-down wording, the caps (min(1200, 3000 - 100) = 1200 lines, 40
      names per list, 200-char wrap), what it never reads or calls (no
      writes, no arithmetic on a secret absorb, no protected API, the AceEvent
      registry walked with pairs), the `debug events`/`debug hold` words, the
      trace tags, and which to paste.
    - ARCHITECTURE.md: the Tier-2 `debug.md` row reads Present, with the
      trigger.
    - module-map.md: the DebugLogSetup descriptor snippet gains brandName,
      diagnostics and the one-key L; the instance surface gains
      RunDiagnostics; the stub paragraph names its library-absent line and
      points at debug.md.
    - smoke-tests.md: new section V (S1-S5, S7, S8, S11 and the
      library-absent arm: append, section order, ungated, both forms while
      disabled, the long alias, no alias, combat and restricted content, Copy
      clean, the 3000-line cap); step 102 no longer claims no descriptor gets
      an L; a triage reference for the report.
    - common-tasks.md: "Add a section to the diagnostics report" and a
      see-also entry; slash-dispatch.md and scope.md point at debug.md.

    Already current, checked and left alone: the buffer sites
    (ARCHITECTURE:75, module-map :306/:362, smoke-tests :95 read 3000) and
    the LibKa0s file count (ARCHITECTURE:49, module-map :757/:910,
    performance.md:390 read twenty-two), rolled at DR-AT-01's sync-docs; the
    verb counts (19) in slash-dispatch, module-map, schema and scope, rolled
    at DR-AT-03.

    TDD: tests/test_docs.lua's "every Tier 2 documentation-map row agrees
    with docs/" went red when debug.md was added under the old Not applicable
    row, and green once the row flipped. Documentation only; no case added,
    so test-cases.md and the README badge stand at 802. Every edited file
    CRLF.

    Gate: lua tests/run.lua 802 passed, 0 failed, 0 skipped; luacheck 0
    warnings / 0 errors in 66 files; lizard -C 15 -w clean (libs and
    tests/_kit excluded); largest authored Lua file 1447 lines.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit 0ede784da21a1f35da143c833e037e2d38d09b1b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 09:07:36 2026 +0530

    DR-AT-04: README gains ## Reporting a bug; Troubleshooting and FAQ point at it

    documentation-§1 item 9 (standard v2.68.0, STD-17): a `## Reporting a bug`
    section between `## Troubleshooting` and `## Issues and feature requests`,
    the standard's text verbatim with `/at` as the slash. Step 3 reads "include
    it with your bug report"; the section names no destination and carries no
    GitHub link (owner ruling DR-OW-01).

    STD-18: Troubleshooting gains the row "Something looks wrong and I want to
    report it -> Follow Reporting a bug below." No existing row told players to
    paste logs another way; the FAQ "How do I see debug logs?" answer now ends
    with a pointer to the section for logs sent with a bug report.

    TDD: a new case in tests/test_docs.lua pins the section body to the
    standard's text with /at, its place between Troubleshooting and Issues and
    feature requests, the absence of any link or "github", and the pointer row.
    It was seen failing against the old README first. test-cases.md
    regenerated (test_docs 4 -> 5, total 801 -> 802), README badge 802/802,
    module-map row 49 and the common-tasks test table describe the new rule.

    Verification (plan section 4, -04): the section diffs clean against the
    STD-17 block with /<slash> -> /at; no GitHub link in it. De-AI pass
    (humanize) on the added prose: no change warranted.

    Gate: lua tests/run.lua 802 passed, 0 failed, 0 skipped; luacheck 0
    warnings / 0 errors in 66 files; lizard -C 15 -w clean (libs and tests/_kit
    excluded); largest authored Lua file 1447 lines; every edited file CRLF.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit a2c89b3f2cea0a4e0ac7d75d1b43a020f47aeeaf
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 09:02:59 2026 +0530

    DR-AT-03R: Read the diagnostics media rung off LSM, not off the resolved path

    Independent review of DR-AT-03 (33e302b). The media section decided its
    fallback flag by comparing the resolved path with C.FALLBACK_*. The shipped
    border and font names ("Blizzard Tooltip", "Friz Quadrata TT") resolve under
    LSM to the very paths C.FALLBACK_BORDER and C.FALLBACK_FONT hold, and the
    "Blizzard" statusbar resolves to C.FALLBACK_TEXTURE. So every default install
    would report fallback=yes on the border and font rows even though LSM
    resolved them, which points a maintainer at a broken media install that does
    not exist.

    The row now prints rung=lsm|lsm default|fallback, asked of LSM itself
    (Fetch with noDefault, then without): lsm when LSM knows the stored name,
    lsm default when LSM answered its own default for a name nobody registered
    (a SharedMedia pack uninstalled), fallback when there is no LSM or no answer.
    Both Fetch calls are pcall'd. Still read-only; no absorb value is involved.

    TDD: the new case in tests/test_diagnostics.lua (a fake LSM mapping the
    shipped names onto the fallback literals, and an unregistered bgTexture)
    was red before the fix and is green after.

    Docs: module-map rows 17a and 55a (line counts and wording), common-tasks
    test table, test-cases.md regenerated (800 -> 801), README badge 801/801.

    Gate: lua tests/run.lua 801 passed, 0 failed, 0 skipped; luacheck 0
    warnings / 0 errors in 66 files; lizard -C 15 -w clean (libs and tests/_kit
    excluded); no authored file over 1500 lines; every edited file CRLF.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit 33e302b021e24fa6a14798862c7d46be466f52a2
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 08:56:52 2026 +0530

    DR-AT-03: Add /at diagnostics on the LibKa0s helper (DX-AT), /at debug events folded in

    The diagnostics dump of debug-logging-§14 (standard v2.68.0, DX-AT), built
    on LibKa0s-DebugLog-1.0's DebugLogDiagnostics helper (v1.60.0). The library
    writes the markers, the identity header, the per-section pcall, the cap and
    the chat line; this addon supplies sections only.

    - modules/Diagnostics.lua (new, TOC after Timer): thirteen read-only
      sections. state (schema stored and code, profile, stored enabled against
      the latch, test mode: none), lifecycle (holds, perf probe, bus), settings
      (rows off their default as path = value (default); the six globals and
      global.minimap.shown always; state.debugConsole), units (switch, mirror,
      UnitExists, ShouldShowBar with NS.VisibilityReason and
      NS.LastAppliedVisibility), frames (shown/visible, alpha against
      GetBarAlpha, scale, size, live vs stored point, default-position flag,
      handle), media (LSM name, resolved path, fallback flag), colors (class
      token, class-color flags, resolved RGBA), absorb (gated by IsConcatSafe;
      a secret prints <secret>), events (AceEvent set read off its registry with
      pairs, each unit frame's two events; one stood-down line while down),
      rejected events (/at debug events folded in; the topic word stays),
      repaint (NS.IsRepaintPending, throttle window, hold remaining), counters
      (NS.SessionCounters, since last combat start) and ui (settings panel,
      launcher, missing libraries). No setter, publish, hold, timer, Show/Hide,
      OpenOptionsPanel or Clear; no compare, conversion or arithmetic on an
      absorb value. Loads on a library-less install too.
    - core/DebugLogSetup.lua: the descriptor gains brandName
      (NS.Constants.BRAND), diagnostics (a closure over NS.Diagnostics.Sections)
      and L, a plain one-key table routing DIAG_WRITTEN through NS.L (never the
      locale table itself).
    - settings/Slash.lua: the diagnostics COMMANDS row straight after debug
      (18 -> 19 verbs), its text through NS.L; runDebug tests `diagnostics`
      first, before on/off, the topic words and the window toggle. No
      diag/dump/dx alias: `debug diag` toggles the window like any unknown word.
      The live set picks the verb up from Slash 16's LIVE_VERBS unchanged.
    - locales/enUS.lua: the row's help text and the chat line.

    Tests (STD-19, TDD: the new cases were red before the code):
    tests/run.lua wires Kit.diagnostics, so the kit's test_diagnostics_contract
    runs against /at's own dispatcher (both forms, any case, markers with the
    brand, append, ungated, while disabled, no alias) in place of its declared
    skip. New tests/test_diagnostics.lua (11 cases): the row and its locale key,
    every DX-AT section for every unit with none failing and under 150 lines,
    changed and always rows, a secret absorb, the stood-down wording, a report
    that changes no registration/timer/hold/throttle/flag/panel/console,
    rejected events folded in, a raising section costing one line, the capped
    ending, the one localized chat line, and the library-absent arm through both
    forms on a degraded load.

    Falsification: renaming the `diagnostics` branch in runDebug turns four
    cases red (three kit contract cases and the library-absent case); restored.

    Verification (plan section 4): grep -rniE '"(diag|dump|dx)"' settings core
    modules is empty; the kit contract dispatches both forms while disabled.

    Docs: test-cases.md regenerated (783 -> 800), README badge 800/800, verb
    counts 18 -> 19 (ARCHITECTURE, module-map, schema, scope, slash-dispatch,
    smoke-tests step 8), slash-dispatch live-set row, verb table and debug
    note, module-map rows (enUS, DebugLogSetup, Diagnostics, Slash, run.lua,
    test_diagnostics), ARCHITECTURE module table, common-tasks test table,
    testing.md luacheck file count (66), and the Slash.lua line citations in
    slash-dispatch and smoke-tests. debug.md and the rest are DR-AT-05; the
    README section is DR-AT-04.

    Gate: lua tests/run.lua 800 passed, 0 failed; luacheck 0 warnings / 0
    errors in 66 files; lizard -C 15 -w clean (libs and tests/_kit excluded);
    no authored file over 1500 lines.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit a553c558c8adab3ff4219a85ab19297e382e54a1
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 04:13:28 2026 +0530

    DR-AT-02: Read-only diagnostics seams for the visibility ladder, the repaint throttle and the combat counters

    The diagnostics report (DX-AT, DR-AT-03) needs four pieces of state that
    lived in file-local variables. Each is now published read-only, and none
    of them writes anything:

    - modules/Display.lua: NS.VisibilityReason(unit) wraps the existing
      visibilityReason ladder narration; NS.LastAppliedVisibility(unit)
      returns what ApplyVisibility last applied (nil before the first pass).
    - modules/Timer.lua: NS.IsRepaintPending() asks whether a coalesced pass
      is queued, without arming or canceling one.
    - core/AbsorbTracker.lua: NS.SessionCounters() returns a fresh copy of
      { absorbEvents, repaints, lastAbsorb }, counted since the last combat
      start while debug was on; lastAbsorb is the last non-secret read.

    The modules load on a library-less install too, so the degraded arm is
    the same code; a case loads tests/degraded_env.lua and checks all four
    answer there. No LibKa0s stub changes, so test_surface_parity is
    untouched.

    Tests (TDD, red first): four cases in tests/test_visibility.lua, one in
    tests/test_timer.lua. Suite 777 -> 782 passed of 783 (1 skipped, as
    before); docs/test-cases.md regenerated, README badge and the
    docs/module-map.md rows (13, 16, 17, 39, 40: exports and line counts)
    updated. luacheck 0/0, lizard -C 15 clean.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit a53a4b291a5467d0d7202a98b54c3a817949f756
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 03:59:26 2026 +0530

    docs: sync-docs pass for the LibKa0s v1.60.0 payload

    Content sync only; no document created or restructured.

    - LibKa0s file count twenty-one -> twenty-two (ARCHITECTURE, module-map,
      performance), with DebugLogDiagnostics.lua in the LibKa0s.xml load order
      and under LibKa0s-DebugLog-1.0 in module-map.
    - The console buffer 1500 -> 3000 lines (DebugLog 14, lib.MAX_BUFFER):
      ARCHITECTURE, module-map, and the smoke-test counter lines.
    - Reserved verbs live while disabled twelve -> thirteen (Slash 16 adds
      diagnostics): ARCHITECTURE, module-map's test_disabled row.
    - module-map line counts for the seven files DR-AT-01 changed, kit
      revision 26 -> 27, the kit's four declared suites, the new
      test_diagnostics_contract suite, and test_debuglog's stub case.

    Gate (ka0s-bounded): tests 777 passed, 0 failed, 1 skipped, 778 total;
    luacheck 0/0 in 64 files; libs/LibKa0s matches tag v1.60.0 (diff -r and
    --strip-trailing-cr both empty).

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit a53a4b291a5467d0d7202a98b54c3a817949f756
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 03:59:26 2026 +0530

    docs: sync-docs pass for the LibKa0s v1.60.0 payload

    Content sync only; no document created or restructured.

    - LibKa0s file count twenty-one -> twenty-two (ARCHITECTURE, module-map,
      performance), with DebugLogDiagnostics.lua in the LibKa0s.xml load order
      and under LibKa0s-DebugLog-1.0 in module-map.
    - The console buffer 1500 -> 3000 lines (DebugLog 14, lib.MAX_BUFFER):
      ARCHITECTURE, module-map, and the smoke-test counter lines.
    - Reserved verbs live while disabled twelve -> thirteen (Slash 16 adds
      diagnostics): ARCHITECTURE, module-map's test_disabled row.
    - module-map line counts for the seven files DR-AT-01 changed, kit
      revision 26 -> 27, the kit's four declared suites, the new
      test_diagnostics_contract suite, and test_debuglog's stub case.

    Gate (ka0s-bounded): tests 777 passed, 0 failed, 1 skipped, 778 total;
    luacheck 0/0 in 64 files; libs/LibKa0s matches tag v1.60.0 (diff -r and
    --strip-trailing-cr both empty).

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit 8152b9dc5069f8266f8a9e2e9b514d4aa71a25b3
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 26 03:52:46 2026 +0530

    DR-AT-01: Re-vendor LibKa0s v1.60.0; the DebugLog stub answers RunDiagnostics

    Both payloads copied whole from tag v1.60.0 (commit bed0eb1), spanning
    v1.59.0: WidgetsDragHandle 2 -> 3, DebugLog 13 -> 14, the new
    DebugLogDiagnostics.lua at 1, Slash 15 -> 16, kit revision 26 -> 27.
    The CLAUDE.md provenance line and docs/testing.md's restatement move to
    v1.60.0 in the same commit.

    - core/DebugLogSetup.lua: the library-absent stub gains RunDiagnostics
      (the collection's library-absent line naming /at diagnostics, nothing
      written, returns 0), BuildDiagnostics (an empty report) and DebugVerb.
      The DebugLog parity case went red on the copy alone without them.
    - tests/test_debuglog.lua: a case pins the stub's line, count and routing.
    - tests/run.lua declares the kit's test_diagnostics_contract suite (one
      declared skip until DR-AT-03 wires Kit.diagnostics).
    - The liveVerbs builder already reads SlashLib.LIVE_VERBS, so diagnostics
      is live while disabled with no code change; its comment and the two
      spelled-out live sets (test_disabled step 7, test_slashcmds
      LIVE_WHILE_DISABLED) roll to thirteen reserved verbs.
    - docs/test-cases.md regenerated; README badge 777/778.
    - docs/revendor/2026-09-26-v1.58.0-v1.60.0/: delta, candidates,
      decisions and summary. The diagnostics helper and Slash 16 are adopted
      in DR-AT-03 and the DragHandle close mark in DR-AT-06; nothing was
      declined and no issue was filed.

    Gate (ka0s-bounded): luacheck 0/0 in 64 files; tests 777 passed,
    0 failed, 1 skipped, 778 total; lizard no function above CCN 15;
    largest authored file 1447 lines.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz

commit 257d210fe69a92e85fe2628be1863edf1ced9c9b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Sep 25 00:13:53 2026 +0530

    M6-AT: address review — retire the stale left-click lock/refusal claims
    What: comment and doc corrections only; no behaviour change.
    - docs/slash-dispatch.md: the /at lock|unlock row no longer calls the
      launcher's left click a writer of `locked` (retired rung (b)); the
      menu's Locked entry is the launcher writer, left click writes nothing.
    - settings/Slash.lua: the degraded stub's DisabledLine rationale and the
      Sl:DisabledLine doc comment now name runHold (`/at debug hold`) as the
      caller, not the launcher's refused left click, which no longer exists.
    - docs/module-map.md: the settings/Slash.lua row says the same; the
      settings/Schema.lua row's line count moves 550 -> 551.
    - Beyond the review, the same stale claim in settings/Schema.lua's
      WRITE_THROUGH comment and in tests/test_slashcmds.lua's refused-unlock
      case comment.

    Why: LibKa0s-Launcher minor 4 made left click open settings in either
    state; these citations described the retired behaviour.

    Departures: no new test; the changes are comments and docs only, and
    the existing suites already pin left click writing nothing
    (tests/test_launcher.lua) and no disabledLine being passed.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 257d210fe69a92e85fe2628be1863edf1ced9c9b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Sep 25 00:13:53 2026 +0530

    M6-AT: address review — retire the stale left-click lock/refusal claims
    What: comment and doc corrections only; no behaviour change.
    - docs/slash-dispatch.md: the /at lock|unlock row no longer calls the
      launcher's left click a writer of `locked` (retired rung (b)); the
      menu's Locked entry is the launcher writer, left click writes nothing.
    - settings/Slash.lua: the degraded stub's DisabledLine rationale and the
      Sl:DisabledLine doc comment now name runHold (`/at debug hold`) as the
      caller, not the launcher's refused left click, which no longer exists.
    - docs/module-map.md: the settings/Slash.lua row says the same; the
      settings/Schema.lua row's line count moves 550 -> 551.
    - Beyond the review, the same stale claim in settings/Schema.lua's
      WRITE_THROUGH comment and in tests/test_slashcmds.lua's refused-unlock
      case comment.

    Why: LibKa0s-Launcher minor 4 made left click open settings in either
    state; these citations described the retired behaviour.

    Departures: no new test; the changes are comments and docs only, and
    the existing suites already pin left click writing nothing
    (tests/test_launcher.lua) and no disabledLine being passed.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 4fa2f0ffd640ce51b6c807d913b9943574600711
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Sep 25 00:09:31 2026 +0530

    M6-AT: Re-vendor LibKa0s v1.58.0; launcher menu is Enabled and Locked

    What: copy LibKa0s/ -> libs/LibKa0s/ and testkit/ -> tests/_kit/ whole
    from the local tag v1.58.0 (tag 93cf3ad -> commit 34931c9) via git
    archive; both diff -r checks are empty. Launcher moves minor 3 -> 4, the
    kit stays at revision 26 byte-identical. CLAUDE.md's provenance line and
    docs/testing.md's prose restatement roll to v1.58.0. The delta bundle is
    docs/revendor/2026-09-25-v1.58.0/ (01_DELTA.md, 05_SUMMARY.md), shaped
    like M5's v1.57.0 bundle.

    core/LauncherSetup.lua adopts Launcher minor 4 (launcher-§2, standard
    v2.67.0): left-click opens settings, right-click opens the options
    menu. It passes the two pairs this addon has, matching ADDONS.md's row
    (Enabled · Locked): isEnabled/setEnabled and isLocked/toggleLock. Each
    toggle runs the slash verb's own NS.COMMANDS handler at click time
    (/at enable|disable, /at lock|unlock picked from the stored lock), so
    the SetByPath seam, the stand-down latch, the combat unlock refusal and
    the echo are the verb's. No test-mode pair (options-ui-§15 exemption)
    and no window pair (no primary window). onClick, leftClickLabel and
    disabledLine are removed; version and isLocked stay. The unread
    "Lock / unlock" locale key goes with leftClickLabel.

    Why: the owner's M6 ruling. The copy alone reddened seven cases that
    pinned minor 3's buttons and hints, so copy and adoption share this
    commit rather than landing a red one.

    Tests (written red first): tests/mock_menu.lua, a host fake of
    MenuUtil modeled on the library's repo-local one, installed per case.
    test_launcher pins left-click -> panel with no write, the menu's title
    and exactly Enabled / Locked, per-open state reads, each entry running
    the /at verb's handler (spied on NS.COMMANDS), the disabled gray with
    the note, the no-MenuUtil fallback and no retired field in the setup
    file; tooltip cases re-pin the fixed hints. test_disabled step 8 now
    pins the unGated left click and the grayed Locked writing nothing.

    Docs: README minimap paragraph and badge (776), launcher.md (two
    buttons, options menu), ARCHITECTURE.md, settings-panel.md launcher
    row, smoke-tests.md section U, module-map/scope/schema/slash-dispatch/
    common-tasks mentions, test-cases.md regenerated.

    Gates: lint 0/0 in 64 files, tests 776 passed 0 failed, complexity 0
    warnings, largest authored file tests/test_helpers.lua at 1447 lines.
    Departures: one commit instead of copy-then-adopt (the copy is red on
    its own); disabledLine is dropped too, as launcher-§5 retires it.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit a45c97510ffef684952b02fb53b5833c38383a55
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 23:11:28 2026 +0530

    M5-AT: Feed the launcher's status tooltip: version, lock, left label

    What: core/LauncherSetup.lua passes the Launcher minor-3 descriptor
    fields the library's always-on status tooltip reads (launcher-§1, the
    owner's M5 ruling): `version` (the TOC's ## Version via NS.Meta),
    `isLocked` (the `locked` setting the left click toggles) and
    `leftClickLabel` (NS.L["Lock / unlock"], rung (b) as ADDONS.md records
    it). isEnabled / disabledLine were already passed and now also feed the
    Enabled line and the disabled hint (`Left-click: disabled — /at enable`).
    locales/enUS.lua gains the one key.

    Not passed, on purpose: `isTestMode` (no Test mode here; options-ui-§15's
    exemption makes the lock the preview), `slash` (the hint's command is
    read out of NS.Slash:DisabledLine()), and `onTooltipShow` (the addon
    never had one and has no lines of its own to append).

    Tests first: six new cases in tests/test_launcher.lua drive the object's
    OnTooltipShow against a recording tooltip and pin the whole five-line
    tooltip, the TOC version and its absence, Locked read on every show with
    its colors, no Test mode line, the disabled state, and the locale route.
    All six were red on the re-vendored library before the descriptor change.

    Docs: launcher.md gains a status-tooltip section; ARCHITECTURE.md's
    Launcher paragraph and documentation-map row, settings-panel.md's
    Minimap button row and README's minimap paragraph mention it.
    docs/test-cases.md regenerated and the README badge moved to 772.

    Gates: lint 0/0 in 63 files, tests 772 passed 0 failed, complexity 0
    warnings, largest authored file tests/test_helpers.lua at 1447 lines.
    Departures: `version` is NS.Meta("Version") rather than NS.Version(), so
    an unreadable manifest draws the label alone instead of "v?".

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 310112cfd96b6a98401a090afb26998156f59494
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 23:07:09 2026 +0530

    M5-AT: Re-vendor LibKa0s v1.57.0 and record its delta bundle

    Copy LibKa0s/ -> libs/LibKa0s/ and testkit/ -> tests/_kit/ whole from the
    local tag v1.57.0 (tag d03e836 -> commit aa37bc9) via git archive. Both
    diff -r checks against the tag are empty and the runner stays executable.
    CLAUDE.md's provenance line moves v1.56.0 -> v1.57.0 in the same commit,
    as does the prose restatement of the vendored tag in docs/testing.md.

    One library file moves a minor: Launcher 2 -> 3, which makes the LDB
    object's OnTooltipShow always the library's status tooltip (launcher-§1,
    standard v2.66.0). No file is added or removed, and the kit stays at
    revision 26 with identical bytes, so only Launcher.lua changes on disk.

    The bundle docs/revendor/2026-09-24-v1.57.0/ (01_DELTA.md, 05_SUMMARY.md)
    follows the RV-AT bundle's shape. No contract blocker: this addon never
    passed onTooltipShow and no test read the object's hook. The descriptor
    adoption (version, leftClickLabel, isLocked) is the next M5-AT commit.

    Gates on the copy: lint 0/0 in 63 files, tests 766 passed 0 failed,
    complexity 0 warnings, largest authored file tests/test_helpers.lua at
    1447 lines. No deviations.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 8a7818a2a38789c5c04330d91f3cf2318ac33931
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 13:26:17 2026 +0530

    AT-26: Revendor standards reference against v2.65.0 (no drift found)

    Ran the /wow-addon:revendor-standards sweep against WowAddonStandards
    v2.65.0 (2026-09-23). The gate was met: the GitHub default branch serves
    STANDARDS.md naming v2.65.0, and origin/master is fdcde97. The section
    files were read verbatim from that commit because raw.githubusercontent
    fetches timed out.

    Findings: none. No file changed.
    - Three-place reference (documentation-§6): TOC `## X-Standard:` carries
      the repo URL, the README badge is the bare unlinked image with `_`
      escapes, and CLAUDE.md "Standards compliance (read first)" keeps the
      stop-and-flag directive and the two-way classification.
    - 3b notation sweep: `grep -rEn '§[0-9]+\.[0-9]' . --exclude-dir=.git
      --exclude-dir=libs --exclude-dir=_kit --exclude-dir=audits
      --exclude-dir=reviews --exclude-dir=automated-tests` gives 0 hits.
      The 126 hits left in frozen audits/reviews/automated-tests bundles
      stay there on purpose. All 1102 filename-§N references resolve inside
      the fetched section ranges. The only non-matching token is CLAUDE.md's
      canonical `filename-§N` placeholder. No doc set is stated as a bare
      count, and nothing uses the retired "drop-in" label.
    - 3c: every CLAUDE.md pointer exists. docs/ has the canonical trio, the
      five record docs and the six Tier 1 docs. No agent-context.md,
      complexity.md, file-index.md or conventions.md.
    - 3d: the standard has no vendored quirks-catalogue section, so there
      is nothing to vendor.
    - 3f: testing.md and automated-tests/README.md already name both the
      commit and release checkpoints. The RESULTS.md lead-in is generated by
      the runner and was not swept.
    - 3g: .gitattributes pins `* text=auto eol=crlf` with the *.sh carve-out
      and binaries marked. 0 tracked files disagree with the pin. No
      renormalization was done.

    Deviation: the item text and verify step expect `v2.65.0` in CLAUDE.md,
    README.md and AbsorbTracker.toc. documentation-§6's canonical forms
    carry no version: X-Standard is the URL, the badge is fixed, and the
    CLAUDE block is unversioned. The revendor-standards rules also forbid
    writing a standard version into the reference, and the fetched standard
    wins. So nothing was stamped, and that verify grep correctly finds no
    hit in those three files. The follow-up code MUSTs that v2.65.0 adds
    (the minimap.shown path, /at debug hold) belong to their own items and
    are not part of this reference roll.

    Gates: luacheck 0/0; tests 766 passed, 0 failed; 0 functions above
    CCN 15; the largest authored .lua file is 1447 lines.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 31ce2b0cc8c2661f0b5aa9b13104c7d554d3e757
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 11:31:38 2026 +0530

    AT-DOCS: address review — drop the retired `test` verb from schema, scope and smoke docs

    AT-11 retired `/at test` and NS.COMMANDS (settings/Slash.lua) now has 18
    rows. The sync-docs pass fixed slash-dispatch.md but missed three live docs:

    - docs/schema.md: the non-key/value verb list no longer names `test`,
      and the count is 18 verbs, not 19.
    - docs/scope.md: "the 19 verbs" becomes "the 18 verbs".
    - docs/smoke-tests.md step 8: lists the 18 verbs, says `/at test` now
      answers unknown command, and quotes the `debug` help text as the code
      has it ("`on`/`off` logging, `events`, `hold <value> [secs]`").

    Docs only. luacheck clean, 766/766 tests pass, no function above CCN 15.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit a99cfe79ad04e7183fa229eec96750874a079398
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 11:25:19 2026 +0530

    AT-DOCS: Record the 20260924-112145 automated-test bundle

    The kit revision 26 runner (all four suites, through ka0s-bounded) ran
    over e84b6d8, clean tree, on the remediation branch:

    - lint pass, 0/0 in 63 files
    - tests pass, 766/0/766 (docs/test-cases.md and the README badge agree)
    - perf pass, 6 scenarios
    - complexity pass, max CCN 14, 0 functions above 15, 3 files in the
      1000-1500 band, none over the cap

    The runner rolled RESULTS.md and widened it once with the Commit and
    Tree columns, carrying the eleven earlier rows forward as unknown. This
    bundle replaces 20260916-184524 (1080857 on master, 74 commits back) as
    the current record (AbsorbTracker-A-20). ANALYSIS.md follows the
    AUTOMATED_TESTS.md template. appearancePass fell from 384.2 to 97.8
    bytes/iter. A per-commit replay of the offline perf script pins the drop
    on 7c43ab4, where the unit label and its font plumbing left
    UpdateBarAppearance.

    Watch-list Disposition cells, the only hand-edited column:
    - tests/test_helpers.lua 1447: peel next by helper group, carried
      forward (AbsorbTracker-R-14). History updated with AT-19's +31.
    - tests/test_slashcmds.lua 1318: back under the cap, watch, re-check at
      1400, next seam the /at profile cases.
    - tests/test_widgets.lua 1073: newly in the band after AT-15, accepted,
      watch, re-check at 1300.

    Deviations: the item expected test_slashcmds.lua at about 1200 after
    AT-11. It measures 1318, because AT-02/03/04/09 added slash cases. The
    item named two band files and the run found three: test_widgets.lua is
    new in the band and has been given a disposition. Not a release run:
    no version bump, no Version History entry, no tag.

    Findings: AbsorbTracker-A-20, AbsorbTracker-R-14

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit e84b6d895b6d788d6ed51bbf9308978f61691880
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 11:21:35 2026 +0530

    AT-DOCS: Sync the docs to the v1.56.0 payload and the M3 changes

    The sync-docs pass over README.md, CLAUDE.md, DEPENDENCIES.md and docs/
    after RV-AT and AT-01..AT-25. Most of the ripple landed with each item;
    this commit fixes what was still stale:

    - docs/module-map.md: the tests/_kit/ row still described kit revision
      25 (7326 lines). It now reads revision 26 (7820), with current per-file
      sizes and the three files revision 26 added: asserts.lua (peeled out
      of framework.lua), mock_events.lua and prose_lists.lua. The
      tests/test_envsetup.lua row is 120 lines, not 104, and names the
      dead-rung case AT-16 added.
    - docs/slash-dispatch.md: eighteen verbs, not nineteen (AT-11 moved
      `test` under `debug hold`). `debug` now parses a value and a duration
      under `hold` and dispatches through DEBUG_VERBS, so the sub-verb-tree
      intro no longer says only `profile` carries a table.
    - docs/testing.md: the top-level-ignore row reaches 63 linted files, not
      54. The re-vendor paragraph names v1.56.0, not v1.35.0, as the tag
      CLAUDE.md claims.
    - Stale file:line citations re-derived against HEAD: ARCHITECTURE.md
      events-frames-taint-§8 row, the UnitGetTotalAbsorbs sites
      core/AbsorbTracker.lua:199/:279 -> :225/:305. smoke-tests.md
      AbbreviateNumbers sites Display.lua:412 -> :427 and
      AbsorbTracker.lua:204/:206/:282 -> :230/:232/:308, UnitClass sites
      Data.lua:227 -> :205 and CoreSetup.lua:59 -> :60, and
      test_display.lua:813 -> :766. settings-panel.md, test_data.lua:192 ->
      :200 for the deferred-closure pin.

    Verified unchanged and correct: the CLAUDE.md v1.56.0 provenance line,
    the README Tests badge (766/766) and docs/test-cases.md (its diff
    against `tests/run.lua --list` is empty), the eighteen NS.COMMANDS rows
    against ARCHITECTURE.md and slash-dispatch.md's verb table, and every
    other module-map LOC cell against wc -l. The largest authored file is
    tests/test_helpers.lua at 1447, and nothing is over 1500.

    Comment-citation check over the addon's own source. These were reported
    and not corrected, since the check corrects a code comment only on
    confirmation:
    - tests/test_envsetup.lua:19 cites tests/_kit/mock_base.lua:183 for
      the C_AddOns note, which now sits at :1110.
    - tests/test_perf.lua:572 cites core/PerfSetup.lua:33 for the
      descriptor, which now opens at :35.
    - tests/test_schema.lua:400-402 cites OptionsCompose.lua:240/:284/:313
      and :182-186, now :324/:368/:397 and :248-255, and
      tests/test_data.lua:192, now :200.

    The automated-test bundle (AbsorbTracker-A-20) follows in its own
    commit so that its manifest records this clean commit.

    Findings: AbsorbTracker-A-20, AbsorbTracker-R-14, AbsorbTracker-A-19,
    AbsorbTracker-A-27 (item AT-DOCS; the bundle and issue store follow)

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 4cd2ffae8f0bce846a2a11c25c4bc31e28391419
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 11:14:55 2026 +0530

    AT-25: Record the lapsed re-vendors v1.16.0..v1.54.2 in one span bundle

    Adds docs/revendor/2026-09-23-v1.16.0-v1.54.2/ as the consolidated span
    bundle that audit-review-history sanctions for a lapsed span. It holds
    01_DELTA.md and 05_SUMMARY.md only. Line 1 of 01_DELTA.md follows the
    WS-01 grammar and names every tag the bundle covers. The body maps each
    tag to its vendoring commit (git log -- libs/LibKa0s tests/_kit, with
    the tag read from CLAUDE.md's provenance line at that commit).
    05_SUMMARY.md gives one line per tag: carried by sweep, or the adoption
    commit's sha and subject.

    Resolves AbsorbTracker-A-01.

    Deviations from the item text:
    - The span is 27 tags, v1.16.0 -> v1.54.2, not the 24 tags
      v1.18.0..v1.53.0 ending at v1.55.0. The item says the list must be
      whatever the amended AUDIT.md step-4 script prints, and that script
      also reports v1.16.0 (the "$horizon 00:00" bound picks up the
      horizon's own morning) plus v1.43.0 and v1.54.2 (the kit-only
      re-vendors it now walks). The folder is named for the real first and
      last tags. v1.55.0 already has its own bundle, so it is left out.
      The head -1 | grep | wc -l check therefore counts 29 (27 plus the two
      range ends), not 26.
    - No frozen bundle's base is misstated, so no correction note was
      needed beyond the one about the count. docs/ARCHITECTURE.md and
      CLAUDE.md do not list revendor bundles one by one (ARCHITECTURE names
      the store once), so neither needed an edit.

    Verify: the amended step-4 check prints 0 unrecorded (37 vendored, 37
    recorded). luacheck 0/0 in 63 files; tests/run.lua 766 passed,
    0 failed; the complexity scan shows no warnings.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 5176809a82192caf519456bd38cccd078200b1be
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 11:04:58 2026 +0530

    AT-24: Spill the ARCHITECTURE hub back under documentation-§3's rule

    docs/ARCHITECTURE.md was 841 lines (788 at the audit) with Settings
    Schema at 123, Message Bus at 73 and Event Subscriptions at 89, all past
    the ~60-line spill MUST. It is now 400 lines and no section exceeds 55.
    Everything moved, nothing was deleted; each spilled section keeps a
    summary and one link.

    - Settings Schema (123 -> 29): the hub keeps the row counts, the
      runtime name, the NS.SetByPath seam, the no-registry statement and one
      sentence per named non-setting state (owner and writers, as
      architecture-§5 requires in this section). The runtime binding, the
      bulk bracket, the no-registry argument and both named states' full
      writer lists moved into docs/schema.md as new sections; the validator
      paragraph was already there and was not copied again.
    - Message Bus (73 -> 23): the receiver rule and the catalog table stay
      (per the audit's C5 design). The Bus-record/stand-down paragraph, the
      fan-out, what is not on the bus and the AceDB callback paragraph moved
      to a new docs/message-bus.md. Its Conditional row flips from Not
      applicable to Present, as the spill target of the hub's ~60-line rule
      (the more-than-ten-message trigger is not met: five messages).
      documentation-§3 names message-bus.md as this section's spill target,
      so no upstream ruling was needed.
    - The disabled-state essay (88 -> 7) moved whole to a new Tier 3
      docs/lifecycle.md, registered in a new "### Addon-specific
      (documentation-§3, Tier 3)" table after "### Verification and record".
    - Event Subscriptions (89 -> 45): the bullets are condensed to a summary
      with one link to data-flow.md; the facts data-flow.md lacked (the
      latch gate at OnEnable, frames built once, the old two-frame packing,
      rejected-event reporting, the degraded stub) moved there as a new
      subsection. The carve-out subsection stays, as three docs link to it.
      The stale "register the monospace font with LSM" OnInitialize step
      (moved to core/MediaSetup.lua long ago) is dropped from the summary.

    Links into the moved text were repointed (data-flow.md, profiles.md,
    schema.md, module-map.md, performance.md). Tests: 766/766 green, case
    count unchanged, so docs/test-cases.md is untouched; lint 0/0;
    complexity clean. tests/test_docs.lua pins no moved heading, so it
    needed no change.

    Finding: AbsorbTracker-A-13 (audit AT-75).

    Deviations from the item text:
    - Three blocks were moved that the item did not name, because the
      three it named left the hub at ~480 lines against its <=400 target:
      the Launcher section to a new Tier 3 docs/launcher.md; the retired
      register rows and "Recorded, but not deviations" to a new Tier 3
      docs/recorded-decisions.md (the register keeps a one-paragraph
      pointer); and the per-profile stamp's "in full" argument, which
      duplicated profiles.md's "The v3 lift, and why the gate is
      per-profile", is replaced by the register row citing that section.
      Both new docs are registered in the Tier 3 table.
    - Paragraphs that restated a topic doc were shortened to pointers: the
      Overview's vararg paragraph (module-map.md), the Slash Commands
      disabled-gate and no-test-verb paragraphs (slash-dispatch.md), the
      Known Limitations English-only bullet (the register row) and the
      agent-context.md paragraph (documentation-§3).
    - The item cites :118-233 / :234-306 / :400-486 / :630; the file had
      grown since the audit, so the moves followed the headings.
    - README.md and CLAUDE.md list no doc that moved, so neither changed.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 2e941998d1916d49b2e04ce199fa20aeb51f173b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 10:53:16 2026 +0530

    AT-23: Retire the per-unit frames register row as the §1 carve-out

    The per-unit RegisterUnitEvent frames meet every condition of the
    events-frames-taint-§1 unit-filter carve-out, so the register row that
    called them a deviation reads as a deviation that is not one.

    - docs/ARCHITECTURE.md: delete the events-frames-taint-§1 row from
      "## Documented deviations" (3 rows remain: savedvariables-§1,
      events-frames-taint-§8, localization-§1); delete "### The per-unit
      event frames, in full"; add "### The per-unit frames are the
      unit-filter carve-out" under "## Event Subscriptions", naming each
      condition by symbol (one SetScript OnEvent plus RegisterUnitEvent
      through NS.SafeRegisterUnitEvent; held at addon.__unitEventFrames;
      UnregisterAllEvents in core/Lifecycle.lua StandDown; built once while
      __unitEventFrames is nil, then reused). Reword the Event Subscriptions
      bullet to cite the carve-out.
    - core/AbsorbTracker.lua: comment only, same rewording.
    - docs/data-flow.md, docs/module-map.md, docs/midnight-quirks.md: reword
      to "the events-frames-taint-§1 unit-filter carve-out" and link the new
      design note; midnight-quirks now says one frame per unit (player,
      target, focus).

    Resolves AbsorbTracker-A-11.

    Deviations: the item's line cites had drifted. data-flow.md is :82 (not
    :77); module-map.md is :430 and :810 (not :425/:807), and :900 carried
    the same "documented events-frames-taint-§1 deviation" wording, so it
    was reworded too; midnight-quirks.md's line is :124 (the :120 line is
    about unknown event names and is correct as it stands). No "N rows"
    sentence existed to fix, and no tests/test_docs.lua pin named the
    removed heading. Frozen copies under docs/investigations and
    docs/superpowers are untouched.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 146f2b496dde9ff04f7fc521d9c550face51839f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 10:50:52 2026 +0530

    AT-22: address review — PerfSetup rows name the latch, not suspend/resume

    The core/PerfSetup.lua rows in docs/ARCHITECTURE.md and docs/module-map.md
    (7b) still said the descriptor carries a `suspend`/`resume` pair, which
    contradicted the same rows' latch wording and the code: the descriptor passes
    `lifecycle = NS.lifecycle`, and StandDown/StandUp live in core/Lifecycle.lua.
    Step 0 of NS.ShouldShowBar reads NS.IsStoodDown(); NS.Perf.suspended is a
    view of the latch (R-07).

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 5d8bde7ff5fc0333c5b3a67589e6eb341ef3bc1f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 10:46:43 2026 +0530

    AT-22: Sweep comment and doc drift against the code

    One pass that corrects each stale comment or doc line to what the code
    does. Comments and docs only; lint 0/0, 766/766 cases, count unchanged.

    - settings/General.lua: the tab diagram draws [Minimap button] where
      [Test mode] was; the header says seven rows plus the button pair and
      why there is no Test mode row; the console-path comment sits on
      DEBUG_CONSOLE_PATH again, below unlockGuard's own comment; the stale
      384.5-byte figure gives way to tests/perf.lua's appearancePass; the
      throttle note names NS.GetThrottleWindow().
    - core/PerfSetup.lua, core/CoreSetup.lua, ARCHITECTURE.md, module-map.md:
      the TOC order is CoreSetup -> Lifecycle -> PerfSetup; PerfSetup loads
      after core/Lifecycle.lua, whose latch the descriptor carries.
    - core/AbsorbTracker.lua: StandUp restores what StandDown tore down (the
      Suspend()/Resume() wording is gone; AT-07 had not reworded it).
    - defaults/Profile.lua: settings/Appearance.lua, not {Bar,Border,Font}.
    - ARCHITECTURE.md and module-map.md: nine files bind addonName (named),
      nineteen open `local _, NS`; .luacheckrc names the nine and drops
      CoreSetup.
    - ARCHITECTURE.md localization-§1 row: v1.42.0, not v1.41.0. Settled by
      the vendor: Slash minor 14 (LibKa0s 8512fa1, first tagged v1.42.0) is
      the one the refusal moved into, and 224a5df re-vendored v1.42.0.
    - module-map.md load order: Lifecycle.lua and LauncherSetup.lua added
      to the Core list; file-index line counts rolled for the three edited
      Lua files.
    - settings-panel.md: the General row names the minimap button.
    - A-26: the documentation map names docs/automated-tests/<run>/ and
      docs/perf-analysis/<run>/, and the RESULTS.md row says "generated,
      except the watch list's Disposition column".
    - A-18/A-25: two entries under "Recorded, but not deviations" -- no host
      window so no close-button wrapper (standalone-windows), and the
      nineteen `local _, NS` files with seven grandfathered self-naming
      headers (documentation-§9). The intro now says four entries.

    Findings: AbsorbTracker-R-07, AbsorbTracker-A-26, AbsorbTracker-A-18,
    AbsorbTracker-A-25.

    Deviations:
    - The MINIMAP_PATH comment was already next to its constant (AT-12);
      verified, nothing to do. The ARCHITECTURE.md size census already reads
      1447 lines, which matches wc -l; left as is.
    - module-map.md's file index already listed Lifecycle.lua and
      LauncherSetup.lua; the gap was the "Load order" Core list, fixed there.
    - "Recorded, but not deviations" is a bullet list, not a table, so the
      two "rows" are bullets.
    - The verify grep still hits core/Data.lua:329, which is the body of
      NS.GetThrottleWindow() itself (live code, not a stale comment).

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 72dad39e9f74fc3b1da0d04885b6521f256ae63b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 10:39:24 2026 +0530

    AT-21: Use canonical standard citations in the addon's own files

    Addon half of AbsorbTracker-A-17: citations of the standard now use the
    canonical section-file-§N / bare section-file form.

    - localization-5 -> localization-§5 in tests/prose_waivers.lua (:3, :7),
      tests/test_docs.lua (:194) and docs/module-map.md (:854).
    - .pkgmeta :17, :20, :21: packaging.md:28 -> packaging (comments).
    - lint.md -> lint in .luacheckrc (:9, :14, :77), docs/testing.md (:45
      heading) and tests/test_lintconfig.lua (:1 comment and the three
      failure-message strings at :132, :151, :262).

    The kit's test_prose and the addon's test_docs accept the section sign in
    these .lua comments (both files were already UTF-8); suite 766/0.

    Deviations: the module-map hit is at :854, not :852; .luacheckrc's third
    hit is at :77, not :78; the "every other lint.md hit" clause also reached
    docs/testing.md and tests/test_lintconfig.lua (message strings, no test
    asserts on them).

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 42291e177203fa15a110da6fe7241b0f87bd204f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 10:36:06 2026 +0530

    AT-20: Annotate the load-bearing TOC lines and the conventional group

    Comment lines only in AbsorbTracker.toc, each directly above its file
    line. Five LOAD-BEARING notes say what each file publishes and who
    captures it at file load: Namespace.lua (NS.version, into the perf
    descriptor), Bus.lua (NS.NewBusTarget / NS.MSG, the guarded UNITS
    subscription in core/AbsorbTracker.lua), CoreSetup.lua (NS.Print /
    NS.Util.print and NS.LIBKA0S_MISSING), PerfSetup.lua (NS.Perf upvalue in
    AbsorbTracker, Display and Timer) and Units.lua (NS.Units.DeepCopy taken
    by Database.lua). One "Conventional order, not load-bearing" note covers
    State.lua, Data.lua and Database.lua; it sits above State.lua and names
    the other two, since the three lines are not adjacent. The Lifecycle
    comment is unchanged. The file list itself is unchanged, so
    test_loadorder stays green; CRLF preserved.

    Findings: AbsorbTracker-A-05, AbsorbTracker-A-06, AbsorbTracker-A-07,
    AbsorbTracker-A-08, AbsorbTracker-A-09.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit de4dac307299e8f72bd3d47404613287a1af0e3d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 10:29:56 2026 +0530

    AT-19: Hand three chat lines' parts to the printer; re-measure §8 row

    Three pre-formatted chat lines outside the events-frames-taint-§8
    register row's scope now hand their parts to NS.Print instead of
    building the line first (the §8 SHOULD half):

    - core/DebugLogSetup.lua (library-absent stub SetEnabled):
      NS.Print("debug logging", on and ON or OFF)
    - core/Lifecycle.lua (library-absent hold set PrintHolds):
      NS.Print(addonName .. ":", holds or "no holds")
    - settings/UnitPanel.lua (RenderUnitPanel failure report):
      NS.Print("Unit panel render failed:", err) -- NS.Print SafeToStrings
      each part, so the raw err loses nothing.

    NS.Print joins parts with one space, so all three lines are
    byte-identical to before. One output case per site pins that (none
    existed): tests/test_debuglog.lua (degraded SetEnabled on/off acks),
    tests/test_disabled.lua (degraded PrintHolds, empty and two holds),
    tests/test_helpers.lua (a raise in the unit panel body). Each was
    green on the old code and confirmed red under a changed separator
    (a part carrying its own trailing space).

    docs/ARCHITECTURE.md events-frames-taint-§8 register row: re-measured
    with the audit's recorded grep (docs/audits/2026-09-23/03_EVIDENCE.md,
    AT-78) at this commit: 19, all in settings/Slash.lua; Schema.lua has
    none left. Ripples: README badge and docs/test-cases.md 763 -> 766,
    module-map line counts for the three suites, and the layout-cap census
    note (test_helpers.lua 1447 lines, still the largest, under the cap).

    Finding: AbsorbTracker-A-16 (audit AT-78).

    Deviations: the item expected the re-measured count near 17; it is 19
    at this commit (AT-03/AT-04/AT-11 added Slash.lua lines), so 19 is
    written. The row's recorded grep contains pipes, which would split a
    Markdown table cell, so the row cites the evidence file for it
    instead of inlining it.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit c15d28c64b82ed9a9a93eae0e885622acab943a2
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 10:23:55 2026 +0530

    AT-18: Read PARENT_TITLE from C.BRAND; drop schema printer's [AT] arm

    settings/OptionsSetup.lua: PARENT_TITLE is now NS.Constants.BRAND (the
    local name is kept). Constants loads well before OptionsSetup, so the
    brand string has one literal again (AbsorbTracker-R-10).

    settings/Schema.lua: chatPrint is `NS.Print(line)`, resolved at call time
    so suites can still spy on it. The `elseif DEFAULT_CHAT_FRAME` arm with its
    hand-typed '|cFF00FFFF[AT]|r' tag is deleted: CoreSetup defines NS.Print on
    both arms before Schema loads, so it could never run, and it was a second
    copy of NS.PREFIX that slash-commands-§4 forbids (AbsorbTracker-R-08).

    Tests (red first, for the right reasons): test_optionssetup asserts the
    canvas name equals NS.Constants.BRAND and that PARENT_TITLE's source reads
    the constant; test_schema spies NS.Print across a ValidateSchema shape
    error and asserts Schema.lua carries no "[AT]" literal and no
    DEFAULT_CHAT_FRAME write. docs/test-cases.md regenerated (763), README
    badge 763/763; ARCHITECTURE, settings-panel and module-map (brand source,
    Schema.lua/test_schema.lua/test_optionssetup.lua line counts) rippled.

    Deviations: the item cites Schema.lua:233-239 and test_optionssetup:297;
    the code sits at Schema.lua:338-344 and the panel-name assert at :320.
    The source-text asserts are added on top of the item's behavioural asserts
    so the new tests are genuinely red before the change (the item's own
    asserts pass on the old code because NS.Print is always defined).

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 070d56aef74b34b3cc33029eb2620c0ce3b8652c
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 10:19:35 2026 +0530

    AT-17: Prune the eight read_globals no authored file reads

    Remove C_Timer, hooksecurefunc, CreateColor, PlaySound, strsplit,
    strtrim, tinsert and tremove from .luacheckrc read_globals. No authored
    file under core/, modules/, settings/, defaults/, locales/ or tests/
    (excluding tests/_kit) reads any of them; the only C_Timer hit is the
    comment at settings/OptionsSetup.lua:144, which stays. With them gone a
    raw C_Timer or hooksecurefunc call lints red, which enforces
    library-stack-§1's AceTimer rule. A short comment in the table says so.

    Lint config only: luacheck stays 0/0, tests 762/0, lizard clean.

    Finding: AbsorbTracker-R-09

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 44c6fdfea4080a6de4adab43ecb543124cf901c3
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 10:18:25 2026 +0530

    AT-16: address review — module-map EnvSetup inventory row matches the two-rung ladder

    The file-inventory row for core/EnvSetup.lua still described the deleted
    pre-11.0 _G rung and called the file the only one naming a deprecated API.
    It now says the file is the only one that reads TOC metadata, spells the
    ladder as Env, then C_AddOns.GetAddOnMetadata, then nil, records why the
    bare-global rung went, and carries the file's current 94-line count.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 34e21fa7f00427016c2916517dfea635b696f8d3
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 10:15:14 2026 +0530

    AT-16: Delete the dead GetAddOnMetadata global rung from NS.Meta

    core/EnvSetup.lua's library-absent ladder in NS.Meta fell back to the
    pre-11.0 bare GetAddOnMetadata global after C_AddOns. No client the TOC's
    ## Interface line admits provides that global, so the rung could never
    reach a working call. compat (WowAddonStandards v2.65.0) rules a dead
    rung deleted rather than kept or shimmed, and its new applicability
    condition means deleting it brings no core/Compat.lua back: this addon
    calls no deprecated or version-variant client API outside LibKa0s's
    majors.

    - core/EnvSetup.lua: rung deleted; header and doc comment now describe
      the ladder as Env, then C_AddOns, then nil.
    - .luacheckrc: GetAddOnMetadata dropped from read_globals (unreferenced).
    - tests/test_envsetup.lua: new degraded-env case, library and C_AddOns
      absent with a global mock present, answers nil and never calls the
      mock (red under the restored rung: got 9.9.9).
    - docs/ARCHITECTURE.md compat-layer map row cites the applicability
      condition; the metadata invariant, docs/module-map.md EnvSetup entry
      and docs/scope.md now describe the two-rung ladder.
    - docs/test-cases.md regenerated (762); README Tests badge 762/762 (it
      was stale at 759 before this change).

    Finding: AbsorbTracker-A-15 (audit AT-77).

    Deviations: the item cites docs/ARCHITECTURE.md :626 for the
    compat-layer row; it sits at :660. The header ladder line cited as :9
    is in the "WHAT A DEGRADED INSTALL GETS" block (:33-38); :9 only named
    the old Compat member, reworded so the verify grep stays empty.
    docs/scope.md also described the global rung and was updated too.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 19761b88941b3efa67356748710d78560fa86a63
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 10:10:12 2026 +0530

    AT-15: Decline RenderTabbedSchema opts; pin the Appearance strip

    Evaluated LibKa0s v1.56.0's O.RenderTabbedSchema opts (OptionsTabs
    minor 4: tabs, cfg, disabledFor, disabledNotice, chrome) for the
    Appearance page's hand-built strip in settings/UnitPanel.lua
    renderUnitPanelBody step 2, against the item's four adoption conditions:

      (i)   PageHeader before the call survives and ctx.__bannerHeight feeds
            the strip's reservation: holds.
      (ii)  rows from rowsForPage(pageKey, ctx.unit): holds.
      (iii) disabledFor(cfg) re-evaluated per render and tab click: holds.
      (iv)  skipRender rows stay out of the strip: FAILS. The library's
            partition keys on row.group alone, so the mirror row
            (skipRender, group "Link") would become a sixth tab on target
            and focus.

    Also found, outside the four: disabledFor draws the notice above rows
    that are still drawn (disabled). This page draws the hint in their
    place. And the library's tab click (ClearScroll plus a re-render of
    itself) drops the page's two-tier mirror refresher. Declined with no
    code change. Filed tusharsaxena/AbsorbTracker#32 (enhancement,
    state:triaged, severity:low). It names condition (iv) and the re-check
    trigger, which is the next Options minor.

    Tests (tests/test_widgets.lua), the host pin of its own composition:
    - For every unit in NS.Units.LIST and every tab: the TabStrip spec's
      keys equal the schema's non-skipRender groups in declaration order.
      Each tab draws exactly its group's rows. ctx.__bannerHeight > 0 and
      ctx.chromeHeight >= ctx.__bannerHeight.
    - target and focus, mirrored: every tab draws the hint and no
      appearance rows.
    Mutations confirmed red: partitionTabs keeping skipRender rows (sixth
    tab), and renderUnitPanelBody ignoring IsMirrored (rows drawn).

    A-04: the General page's chromeHeight > 0 assertion now carries a
    comment. The strip is library-drawn (O.TabStrip via
    O.RenderTabbedSchema), so the wrap-invariance pin belongs to LibKa0s's
    suite and is not duplicated here (options-ui-§13 Testing, testing-§8).

    Ripples: docs/test-cases.md regenerated (759 -> 761). The
    docs/module-map.md test_widgets.lua row is now 1073 lines and names the
    new pins.

    Finding: AbsorbTracker-A-04.
    Deviation: the item's mutation "disabledFor answers false" only applies
    to an adoption. On this decline, the equivalent host mutation
    (IsMirrored ignored) is the one confirmed red.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit a9de87e5bf8aee73e78659c67d4e49c2a2a87a7a
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 10:04:28 2026 +0530

    AT-14: address review — module-map and comment ripple for the Perf and Lifecycle cases

    dc477fc grew tests/test_surface_parity.lua to nine seams and gave
    Kit.setSurfaceSource a fifth instance row, but left the prose describing
    both behind.

    - docs/module-map.md, tests/run.lua row: 139 -> 142 lines; the surface
      source now maps five majors to instances (Lifecycle among them) plus
      Bus and Schema to their library tables.
    - docs/module-map.md, tests/test_surface_parity.lua row: 236 -> 286
      lines; seven seams -> nine (adds Perf and Lifecycle); "the four
      library-backed seams" -> every library-backed seam but Perf uses the
      by-name form; notes the Perf case's reached-subset check.
    - tests/run.lua comment: "all four ... stubs mirror an INSTANCE" -> five.
    - tests/test_surface_parity.lua header: the same stale "four" and
      "all three stubs" counts.

    Comments and docs only. luacheck 0/0, 759/759 tests, lizard no
    thresholds exceeded.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit dc477fc0cbc4b100af6401f8f6889f9eb701dbc2
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 10:01:57 2026 +0530

    AT-14: Add stub-surface parity cases for Perf and Lifecycle

    tests/test_surface_parity.lua now covers nine seams, not seven. Two new
    cases gate the two degradation stubs that had no parity check:

    - Perf: the member set the host reaches, derived with
      grep -rohE '\bPerf[.:][A-Za-z_]+' core modules settings
      ({on, suspended, Note, OnCommand}), must be present on both NS.Perf
      (live) and the degraded load's NS.Perf, and a function degraded
      wherever it is a function live. The whole-surface by-name form is not
      used: the live instance publishes far more than the four-member stub.
    - Lifecycle: tests/run.lua registers NS.lifecycle as the live surface of
      LibKa0s-Lifecycle-1.0 in Kit.setSurfaceSource, and the case uses the
      by-name form. Measured at this commit the live instance publishes
      nothing beyond the stub's nine members, so the ignore set is empty.

    Proved by mutation: removing Note from core/PerfSetup.lua's stub turns
    the Perf case red ("Note is missing degraded"), and removing Holds from
    core/Lifecycle.lua's stub turns the Lifecycle case red ("Holds is
    missing"). Both reverted. docs/test-cases.md regenerated; README badge
    757 -> 759.

    Resolves AbsorbTracker-A-10.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit c32be6917d48f8b8e7232c268e45efe3182cfd74
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 09:59:13 2026 +0530

    AT-13: address review — module-map test_data.lua row to 544 lines

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 05c0be3ea5ca60fc068f9c3b450e9d54083b8b8e
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 09:57:34 2026 +0530

    AT-13: Delete the test-only player aliases from the production namespace

    modules/Bar.lua no longer publishes NS.bar / NS.statusBar / NS.valueText /
    NS.backdropInfo. No production code read them; they survived only as a
    handle for the test harness. With the four assignments and their comment
    gone the suite went red at exactly the alias reads (39 cases), and every
    read is now NS.bars.player / NS.bars.player.statusBar / .valueText /
    .backdropInfo in tests/test_display.lua (46), tests/test_debughold.lua (3),
    same meaning. The file header comment is updated to match.

    tests/test_data.lua's "player alias points at the player frame" case
    asserted the aliases themselves; rewritten as NS.bars.player it would
    compare a value with itself, so it now asserts the four keys stay off NS
    (indexed by string, so the verify grep stays empty). The case count is
    unchanged at 757; docs/test-cases.md regenerated for the new case name.

    Doc ripples: docs/module-map.md (the NS state list, the Bar API block, and
    the Bar.lua row: 172 -> 159 lines, no aliases), docs/ARCHITECTURE.md's
    Bar.lua row, and docs/midnight-quirks.md's SetBackdrop note, which still
    named the single shared NS.backdropInfo table.

    Findings: AbsorbTracker-R-13

    Deviations: the test_data.lua alias case asserts the aliases' absence
    instead of a literal rewrite (a rewrite would be tautological).
    midnight-quirks.md also updated, not named in the item.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 6e4f2207f2e0bb3fd3250fcb74c1e7a20f70b361
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 09:52:29 2026 +0530

    AT-12: Rename the minimap row's CLI path to global.minimap.shown

    The minimap row's path now reads in the row's own sense (launcher-§3,
    standard v2.65.0 / WS-06): C.MINIMAP_PATH = "global.minimap.shown".
    Storage is unchanged: LibDBIcon's own db.global.minimap.hide, inverted by
    the row's get/set in core/Data.lua. No `shown` key is ever stored
    (anti-pattern #81), so there is no SavedVariables migration and no
    schema-version bump; defaults/Profile.lua minimap.hide = false is as-is.

    - core/Constants.lua: the constant's comment is moved directly above it,
      after the BRAND block (it had been split from the constant by that
      block), and rewritten: CLI name reads SHOWN, storage stays
      minimap.hide, get/set invert, no `shown` key stored.
    - settings/Schema.lua: defaultsRoot answers nil for a row that owns its
      storage (type(row.get) == "function"), architecture-§5's closure-backed
      exemption, so the validator does not report global.minimap.shown
      missing from the defaults. Its comment and the resetExempt comment
      name the new path. resetExempt / reachedByProfileReset key off the
      constant and are unchanged.
    - core/Data.lua and settings/OptionsSetup.lua comments name the new path.
    - Docs: ARCHITECTURE.md (path lists, launcher visibility paragraph,
      validator exemption, named-reset note), settings-panel.md,
      slash-dispatch.md, schema.md (validator exemption), module-map.md
      (path mentions, LOC cells for the touched files), smoke-tests.md U.6
      (the CLI read and the old spelling). test-cases.md regenerated;
      README Tests badge 752 -> 757.

    Tests (red first, tests/test_launcher.lua): get global.minimap.shown
    answers true over hide = false; set ... false stores hide = true and
    MinimapShown() is false; get global.minimap.hide answers "Setting not
    found"; ValidateSchema reports 0 errors / 0 missing; a legacy store
    { hide = true, minimapPos = 200 } reads shown = false, stays hidden,
    keeps minimapPos, and never gains a `shown` key after a set.

    Player-facing CLI rename, for the next Version History roll:
    `/at get|set|reset global.minimap.hide` -> `global.minimap.shown`; the
    old path now answers "Setting not found". A button hidden before the
    upgrade stays hidden.

    Findings: none listed on the item (plan item AT-12; R-07 split comment).

    Deviations: the item cites defaultsRoot at settings/Schema.lua:404-409
    and a :228-231 comment; the function and its doc comment actually sit
    at :526-536, and that doc comment is the one updated. No literal
    `resolved` count exists in tests/test_schema.lua, so nothing was
    re-pinned there. ARCHITECTURE.md lives at docs/ARCHITECTURE.md. The
    storage sentence in ARCHITECTURE.md was reworded ("the db.global.minimap
    table's hide key") so the verify grep for global.minimap.hide is empty;
    schema.md, module-map.md and smoke-tests.md were also updated as ripples.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit ae0c7ba949ab33406f28c976956711632e55ac3e
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 09:46:44 2026 +0530

    AT-11: address review — reword the last `/at test` comment in test_debughold.lua

    tests/test_debughold.lua:7 still spelled the retired verb as `/at test <value> [secs]`,
    so the item's verify grep returned it; 0e089ae's body wrongly said only the README 1.8.0
    Version History row remained. The comment now reads "the top-level `test <value> [secs]`
    verb", as settings/Slash.lua already puts it. The verify grep now returns only README.md's
    1.8.0 row, the declared deviation (release history is not rewritten).

    Lint 0/0, tests 752/752, lizard -C 15 clean.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 0e089ae228759c3657131540f4d3467192b36b89
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 09:43:19 2026 +0530

    AT-11: Move /at test to /at debug hold with a validated duration

    This addon's unlocked view is its preview, and options-ui-§15 and
    preview-mode say an addon in that shape ships no `test` verb
    (anti-pattern #80). The one-shot value hold answers a question unlocking
    does not, so it survives at `/at debug hold <value> [secs]`, where WS-06
    (2) puts a kept value hold.

    settings/Slash.lua
    - The `test` row and runTest/runTestHold are gone. DEBUG_VERBS gains
      `hold`, and runDebug now hands each sub-verb the rest of its line.
    - runHold: parseHold refuses a missing or NaN value and any duration
      that is not a number from 0.5 to 60 (default 5), printing HOLD_USAGE
      ("Usage: /at debug hold <value> [secs] — secs from 0.5 to 60, default
      5") and holding nothing. It announces "Holding <v> on the bars for
      <secs> s" with %g, so 2.5 reads as 2.5 rather than %d's "2".
    - `debug` stays live while disabled, but a hold paints the bars, so
      runHold checks the stored `enabled` itself and prints
      Sl:DisabledLine(). on/off/events/bare are unchanged.
    - The debug help row names `hold <value> [secs]`.

    Tests: the /at test section of test_slashcmds.lua and its refused-while-
    disabled case moved to the new tests/test_debughold.lua (run right after
    test_perfcmds) and were retargeted at `debug hold`. Red-first additions:
    negative, over-60, sub-0.5 and non-numeric durations print the usage and
    never reach NS.HoldPreview (spied); 2.5 is announced as "2.5 s" and held
    for 2.5; `test 1000` prints unknown command 'test'; with enabled=false,
    `debug hold` prints the disabled line and holds nothing. test_disabled
    step 7 gains the hold's own refusal (it has no literal 'test' entry; its
    COMMANDS walk dropped `test` by itself). test_slashcmds.lua is now 1318
    lines. docs/test-cases.md regenerated, and the badge is 752/752.

    Comments and docs follow the move: General.lua, Lifecycle.lua,
    Display.lua, Bar.lua, Timer.lua, test_display/test_timer case names,
    README (the hold paragraph and troubleshooting row), slash-dispatch.md
    (verb table, the refused list, hold's own gate, refreshed line cites),
    smoke-tests.md (steps 33-34 and the disabled step, including a stale
    "Test mode ticked" sentence), ARCHITECTURE.md's Slash Commands section,
    module-map.md, settings-panel.md, common-tasks.md and scope.md.

    Findings: AbsorbTracker-A-14, AbsorbTracker-A-24, AbsorbTracker-R-12.

    Deviations:
    - The README Version History row for 1.8.0 still says it added a
      hold-time to `/at test`. That is a record of what 1.8.0 shipped, so it
      was left alone, and the verify grep for '/at test' shows only that
      row.
    - ARCHITECTURE.md has no Slash Commands *table*. The section is prose,
      and the prose was updated.
    - lizard's Lua reader skips a function body that contains `[#t + 1]`, so
      the old runTest never showed up in its output. parseHold matches two
      words instead of building an args table, which lets lizard see runHold
      (CCN 6).

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 4e938b122204771eea67781be2b7d8ab77f9805d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 09:33:07 2026 +0530

    AT-10: address review — module-map LauncherSetup row: 155 LOC, library-owned disabled gate

    The docs/module-map.md row for core/LauncherSetup.lua was left stale by
    e35e134: the LOC column still read 169 (the file is now 155 lines), and the
    row listed the descriptor fields without isEnabled / disabledLine and did not
    say the rung-(b) disabled gate is now LibKa0s-Launcher-1.0 minor 2's, not the
    host's. The row now names both fields and describes the library refusing the
    left click before onClick runs, printing the Slash dispatcher's own line.

    Docs only. luacheck 0/0, tests 746/746, lizard -C 15 clean.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit e35e134717fdb9fab947c81db07a67d17519d1b1
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 09:30:43 2026 +0530

    AT-10: Move the launcher's disabled gate into Launcher minor 2's isEnabled

    core/LauncherSetup.lua: the lib:New descriptor now passes
    isEnabled (NS.GetSetting("enabled") ~= false) and disabledLine
    (NS.Slash:DisabledLine()), both resolved at click time, so
    LibKa0s-Launcher-1.0 minor 2 refuses a disabled addon's left click
    before onClick runs (launcher-§2, slash-commands-§7). The hand-written
    gate is gone from onClick and its comment block is cut to two lines
    naming the descriptor fields. Right-click and openSettings unchanged.

    Tests: tests/test_disabled.lua step 8 and its single-refusal-line
    assertion stay green with the host gate deleted. Mutation-verified:
    removing isEnabled from the descriptor turns step 8 red (and the new
    case); isEnabled answering false turns the new case and the existing
    left-click case red. New tests/test_launcher.lua case: one registered
    object toggles `locked` while enabled, writes nothing while disabled,
    and toggles again once re-enabled (never cached).

    Docs: docs/ARCHITECTURE.md '## Launcher' and docs/slash-dispatch.md say
    the gate is the library's. docs/test-cases.md regenerated and the README
    badge moved 744 -> 746.

    Deviation: the regenerated inventory also picks up the test AT-09's
    review commit (0850145) added without regenerating ("degraded: the
    library-absent line is keyed by its English text"), so the count moves
    by two, not one.

    Findings: none (item carries no finding ids).

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 08501459d2d3b837825c35c4e736e2034cf85c08
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 09:26:48 2026 +0530

    AT-09: address review — key the library-absent line by its English text; fix stale Slash.lua refs

    - localization-§2: locales/enUS.lua keys the library-absent line by the
      English sentence rather than the symbolic LIBRARY_ABSENT token, and
      settings/Slash.lua's stub reads NS.L["%s is unavailable: the LibKa0s
      library did not load."], so the metatable fallback yields English.
      A new test pins the key shape (red before the fix).
    - ARCHITECTURE.md localization-§1 row, module-map.md rows 1 and 19 and
      slash-dispatch.md name the English-text key; module-map row 1's line
      count 53 -> 54.
    - Line refs to settings/Slash.lua moved by bdd4ecf's header: MirrorNote
      :48 -> :58, NS.COMMANDS :61 -> :71. Older neighbouring drift fixed in
      the same pass: Sl:Register :645 -> :713, runProfile :456 -> :524,
      PROFILE_VERBS :408 -> :465 (slash-dispatch.md), the PROFILE_VERBS
      dispatch :469 -> :537 (ARCHITECTURE.md) and AbbreviateNumbers
      :349/:353 -> :392/:396 (smoke-tests.md).

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit bdd4ecf5d8685ed76ad40ccfd31b4ecfc91053c7
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 09:21:52 2026 +0530

    AT-09: Give the Slash stub the LK-18 shape: pinned disabled line, plain rows

    settings/Slash.lua's library-absent stub now takes the shape
    slash-commands-§1 (WS-02) and LK-18 prescribe:

    - STUB_DISABLED_LINE_FORMAT carries LibKa0s-Slash-1.0's DISABLED_LINE_FORMAT
      verbatim (v1.56.0 bytes, em dash as \226\128\148), published as
      Sl.__STUB_DISABLED_LINE_FORMAT and pinned in tests/test_slashcmds.lua with
      T.assertLibraryConstant. The stub's DisabledLine formats it with the brand
      and "/at enable", so it equals the live line, gold escape included. The
      comment that forbade the copy is rewritten.
    - The stub's FormatRow copy is gone. PrintCmd falls back to a plain
      "cmd  desc" row when the library has no FormatRow; LandingRows builds
      the same plain rows.
    - The schema verbs (list/get/set/reset/resetall) print the library-absent
      line through the locale: L["LIBRARY_ABSENT"] = "%s is unavailable: the
      LibKa0s library did not load." added to locales/enUS.lua.

    Red first: four new cases in the degraded/live parity section (the pin,
    the exact library-absent line, no |c in degraded help, degraded vs live
    DisabledLine) failed for the expected reasons, then went green. The kit's
    assertLibraryConstant falls back to LibStub, so the pin resolves the
    library table even though tests/run.lua registers the Slash instance.

    Ripples: ARCHITECTURE.md localization-§1 register row records the routed
    line; slash-dispatch.md's degraded section describes the new stub;
    module-map.md rows (Slash.lua, enUS.lua, test_slashcmds.lua) and line
    counts; smoke-tests.md item 99 walks /at help and /at list degraded;
    docs/test-cases.md regenerated; README badge 744/744.

    No finding ids (item has none). Deviations: none beyond the smoke-test
    step added under item 99 and module-map line counts refreshed.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 3ebbfc165d75d2a8a4b88ea11bbbd40e311c9805
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 09:14:54 2026 +0530

    AT-08: Adopt Schema writeThrough; hollow the Options stub's composers

    settings/Schema.lua declares WRITE_THROUGH = { "enabled", "locked" } and
    hands it to SchemaLib:New as writeThrough (LibKa0s-Schema-1.0 minor 2,
    options-ui-§1 route (a)), so both the live instance (a partial load with
    Schema present and Options absent) and the host stub store those composed
    paths without a row. The announce dispatches a written-through path to
    the host's own reaction, NS.MasterReactions[path], which
    settings/General.lua now publishes (its masterOnChange table): the enable
    edge still moves the stand-down latch and an in-combat unlock is still
    refused. The HostSchemaStub comment says the host writers that reach
    composed rows now write through the declared list.

    settings/OptionsSetup.lua's degradation stub drops ORDER_STEP,
    composeBlock, the ColorPair/FontGroup/BorderGroup/BarGroup/MasterControls
    host copies and Helpers.MASTER_GROUP (its only reader is General's
    build(), which a library-less load never reaches). The five composers
    answer {} (MasterControls also a no-op tail), per options-ui-§1 (v2.65.0)
    and anti-pattern #73. The load-time set is still six members. The file
    goes from 509 to 378 lines. tests/test_surface_parity.lua's Options
    ignore list gains MASTER_GROUP with that reason.

    Tests. Characterization first, green before and after, in
    tests/test_optionssetup.lua with degradedWithDb: degraded /at disable
    stores enabled=false and the latch is down, /at enable reverses it; an
    in-combat /at unlock leaves locked=true and prints the refusal. The
    existing lock/unlock and combat re-lock cases stay green. Mutations
    checked: dropping 'enabled' from WRITE_THROUGH, or disabling the
    announce's reaction dispatch, turns the new cases red. Re-pins:
    tests/test_perf.lua's degraded-schema case becomes three figures (full
    70, degraded 15, and a named gap of 55 attributed per tab: Master
    controls 7, Bar 12, Background 6, Border 12, Text 18), plus degraded is a
    subset of live. A stub composer emitting rows turns it red. The composer
    case in tests/test_optionssetup.lua asserts each composer answers
    #rows == 0 and MasterControls a function tail; its leaf-shape asserts
    are gone.

    Docs: schema.md gains a "With LibKa0s absent" section; settings-panel.md
    degradation stub section; ARCHITECTURE.md Settings Schema, invariant and
    OptionsSetup module row; module-map rows for Schema, OptionsSetup, General
    and the three touched suites (line counts refreshed); common-tasks.md
    suite row; smoke-tests.md step 99 walks the item's smoke; test-cases.md
    regenerated, README badge 740/740.

    Findings: AbsorbTracker-A-02, AbsorbTracker-A-03.

    Deviations: (1) The item's test (c) names tests/test_perf.lua for the
    combat re-lock case; it lives in tests/test_optionssetup.lua and stays
    green there. (2) "the live and degraded builds veto exactly the same rows
    from Reset All" compared the whole live veto set against the degraded
    one, which the hollow composers make unequal by design. It now compares
    over the rows both builds carry (the gap itself is pinned by the perf
    case). (3) The item's docs list did not name smoke-tests.md or
    common-tasks.md. Step 99 claimed a "complete" degraded /at list that the
    Slash stub never gave, so it was rewritten to the item's smoke walk.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 94bed8cbdfab3efea09f2e7aebcf30b3af6022c3
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 09:06:55 2026 +0530

    AT-07: address review — module-map and data-flow ripples for the SafeRegister helpers

    5b6e2cf updated ARCHITECTURE.md's module-map rows but not docs/module-map.md
    or docs/data-flow.md, so both still described the bare registration path
    the item removed.

    - docs/module-map.md: line counts re-synced (State 13, CoreSetup 147,
      Lifecycle 211, DebugLogSetup 127, AbsorbTracker 406, Slash 706, run.lua
      136, test_coresetup 166; Slash's 648 was already stale before AT-07).
      State row names NS.State.rejectedEvents; CoreSetup row names the three
      NS.SafeRegister* publications and the degraded one-rung bodies;
      DebugLogSetup row names the [Init] rejected-events suffix; AbsorbTracker
      row names the pcalled registrations and RegisterLifecycleEvents; Slash
      row names the `debug events` sub-verb; run.lua row's suite count
      corrected to twenty-nine plus the kit's three; test_coresetup row names
      the degraded SafeRegister case; new row 54a for tests/test_events.lua.
    - docs/data-flow.md: the OnEnable diagram shows NS.SafeRegisterEvent /
      NS.SafeRegisterUnitEvent at all seven call sites, RegisterLifecycleEvents,
      and the rejected-list record; the prose after it explains the pcall.

    Docs only. luacheck 0/0, tests 738/738, inventory diff empty.

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit 5b6e2cf5216bbb426ecf53749323f85219e9a4a1
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 09:03:20 2026 +0530

    AT-07: Route every event registration through the SafeRegister helpers

    The client raises on an unknown event name, and a block of bare
    RegisterEvent calls lost every registration after the one that raised.
    All seven call sites in core/AbsorbTracker.lua (the three lifecycle
    events, now driven from a { event, method } array, the two per-unit
    RegisterUnitEvent calls and the two swap events) now go through
    NS.SafeRegisterEvent / NS.SafeRegisterUnitEvent, which core/CoreSetup.lua
    binds to LibKa0s-Core minor 8's helpers. A refused name costs only
    itself, is appended once to the new session list NS.State.rejectedEvents
    and is logged under the Events debug tag.

    - core/CoreSetup.lua: live arm publishes SafeRegisterEvent,
      SafeRegisterUnitEvent and SafeRegisterEvents; the degraded arm carries
      the one-rung bodies (pcall plus append-once, no front gate) per
      docs/api/Core/version-8-docs.md 'Degradation'.
    - settings/Slash.lua: /at debug gains an `events` sub-verb through a
      DEBUG_VERBS table; the help row names it.
    - core/DebugLogSetup.lua: the [Init] summary appends
      ', rejected events: <n>' when the list is non-empty.
    - core/Lifecycle.lua: the ADDON_EVENTS comment names the helper.
    - Tests: new tests/test_events.lua (before test_disabled) covers the
      AceEvent half, the per-unit frame half (kit 26), the IsEventValid front
      gate and /at debug events, and restores the full registration set.
      test_coresetup.lua covers the degraded SafeRegisterEvent. Both were
      confirmed red first (bare calls raise; a stub without pcall raises).
    - Docs: midnight-quirks note, ARCHITECTURE Event Subscriptions bullet and
      module-map rows, slash-dispatch rows; docs/test-cases.md regenerated,
      Tests badge 738/738.

    docs/ARCHITECTURE.md already had a '## Event Subscriptions' section, so
    the item's content went in as a bullet there rather than a new heading.

    Finding: AbsorbTracker-A-12

    Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ

commit be520a50b26bf0e73927c2197e2b253549801359
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 08:04:35 2026 +0530

    AT-06: Stamp schemaVersion per WS-03: floor 0, runner-owned, v2 per profile

    Brings the migration runner in line with savedvariables-§1 as ruled at
    WowAddonStandards v2.65.0 (WS-03).

    - defaults/Profile.lua: NS.defaults.global.schemaVersion is now 0, the
      pre-migration floor. The comment gives §1's reasons: AceDB's
      removeDefaults strips a stored value equal to its default, and AceDB
      backfills a declared default onto a legacy account that stored no
      stamp; 0 has neither problem. The per-profile stamp (default 1, the
      registered savedvariables-§1 deviation) is unchanged.
    - core/Database.lua: NS.SCHEMA_VERSION = SCHEMA_STEPS[#SCHEMA_STEPS].to
      (derived, no second literal) and the suite seam NS.__migrationSteps.
      RunMigrations reads an absent stamp as 0 and walks the ladder in a new
      file-local runLadder: each step runs under pcall; on failure it logs
      "[Migrate] vX -> vY failed: <err>", prints one chat line ("Settings
      upgrade stopped at vX -> vY; saved settings were left as they were")
      and breaks, so the stamp stays at the last completed step and later
      steps do not run. On success it logs and stamps step.to as before.
      RunMigrations is CCN 6, runLadder CCN 4.
    - The v2 step was profile-scoped but cleared only the active profile
      under the account-wide stamp. It now sweeps every stored profile
      through forEachProfile and logs a count line, like v4 and v5.

    Tests (tests/test_database.lua, red first): the global default is 0
    (red: got 1); NS.SCHEMA_VERSION equals the last step's `to` (red: seam
    missing); v2 clears updateInterval from an inactive Raid profile (red:
    Raid kept 0.2); an appended raising step leaves the stamp at
    NS.SCHEMA_VERSION, RunMigrations does not raise, and one chat line names
    the stop (red under: stamping before apply, or no pcall). The existing
    nil-stamp case still reaches 5. The v1->v5 [Migrate] order test now
    expects v2's own count line first (seven lines), and a stale comment
    citing "reads the absent stamp as 1" is corrected.

    Docs: ARCHITECTURE.md (module map row, savedvariables-§1 register row,
    "The per-profile schema stamp, in full"), data-flow.md, profiles.md,
    module-map.md (API block, defaults block, file rows and line counts),
    smoke-tests.md step 51 (stale v4 -> v5, [Init] "schema v5" check, v2
    sweep). docs/test-cases.md regenerated (732); README badge 728 -> 732.

    Deviations: the item names docs/schema.md's migration section, but
    schema.md has none (it covers the settings row schema); the migration
    prose lives in docs/profiles.md and docs/data-flow.md, which were
    updated instead. CLAUDE.md does not quote schemaVersion, so it is
    unchanged. The failure Debug line keeps the ladder's existing arrow
    glyph rather than an ASCII "->"; the chat line uses "->" as specified.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube

commit 7e67f75082893d04a931c28a6377290b7d450b3c
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 07:57:29 2026 +0530

    AT-05: Publish the bar passes once on a profile adopt's enable edge

    adoptProfile (core/AbsorbTracker.lua) re-read the new profile's `enabled`
    through NS.SyncEnabledHold, then called NS.lifecycle:Reevaluate() and
    published UNITS, POSITION, APPEARANCE and REPAINT unconditionally. The
    Reevaluate was a no-op (lifecycle:Set already runs the edge), and on an
    off-to-on switch StandUp (core/Lifecycle.lua) had already published
    POSITION, APPEARANCE and REPAINT, so every three-bar appearance pass ran
    twice.

    Now adoptProfile captures `wasDown` before SyncEnabledHold, drops the
    Reevaluate, always sends UNITS, and sends POSITION/APPEARANCE/REPAINT only
    when the latch did not just stand up. The comment says why. The
    MigrateProfileToV3 call and RefreshOptionsPanel are unchanged.

    Tests (tests/test_database.lua, characterization first): a same-state
    switch sends APPEARANCE once; an off-to-on switch sent 2 before the fix
    (observed red) and sends 1 now (red under: restoring the unconditional
    publishes); an on-to-off switch leaves the latch down and no APPEARANCE
    pass reaches a subscriber. Cleanup restores Default and enabled=true.

    Ripples: docs/test-cases.md regenerated (728), README badge 725 -> 728,
    docs/ARCHITECTURE.md and docs/module-map.md no longer describe the
    Reevaluate call (module-map row 13 line count 374 -> 380, and its
    OnProfileChanged summary now names UNITS and the stand-up skip).

    Resolves: AbsorbTracker-R-11 (review F-010).

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube

commit 53c1c7ea892336c1c7f459a469e998a690538126
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 07:52:57 2026 +0530

    AT-04: Echo the stored value for lock, unlock and enable; fix the comment

    settings/Slash.lua gains a file-local echoStored(path): it refreshes an
    open options panel, reads the path back from the store, formats it
    through its schema row and prints slash-commands-§5's `path = value`
    shape via SlashLib.FormatKV. setEnabled, /at lock and /at unlock all use
    it, so the fixed 'Bar locked'/'Bar unlocked' lines are gone. An in-combat
    /at unlock, which the locked row's onChange refuses and writes back to
    true, now ends on `locked = true` instead of claiming success, and the
    Lock frame checkbox moves with either verb. Help texts say "bars".
    (AbsorbTracker-R-03)

    The /at enable|disable comment no longer describes the removed draw gate
    (VISIBILITY then REPAINT, "gates ShouldShowBar's second rung and nothing
    else ... no event registration changes"). It now says what happens: the
    row's onChange is NS.SyncEnabledHold, which moves the latch's `disabled`
    hold; StandDown unregisters the unit-event frames, the five AceEvent
    registrations and the bus; the dispatcher, COMMANDS and the settings
    registration stay live (slash-commands-§2/§7). (AbsorbTracker-R-05)

    Tests (red first): the lock/unlock case asserts `locked = true/false`
    and no 'Bar locked'; a new in-combat case asserts the refusal, a last
    line ending `locked = true` and the store still true; a new case spies
    NS.RefreshOptionsPanel and asserts one call per verb. Three stale test
    comments that repeated the draw-gate claim were corrected too.
    docs/test-cases.md regenerated, README badge 723 -> 725.

    Docs: README quoted neither old line, so it only carries the badge. The
    docs/slash-dispatch.md enable/disable row did not repeat the draw-gate
    claim and is unchanged; its lock/unlock row now describes the echo.
    docs/smoke-tests.md steps 14e and 30 name the echoed lines, including
    `locked = true` after an in-combat /at unlock.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube

commit 32b60e4137d73df5ade7a6d37a630183b0be30b3
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 07:49:34 2026 +0530

    AT-03: address review — move smoke step 36a before 37 so the tester is on SmokeTest

    Step 36a (/at profile new Default refused) says "you stay on SmokeTest",
    but it sat after step 37, which ends on /at profile use Default. Moved it
    between 36 and 37, where the current profile really is SmokeTest.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube

commit 0e5478b3cdb6be8cb665d7fca671e1f75180957e
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 07:47:04 2026 +0530

    AT-03: Refuse /at profile new on an existing name; pre-check copy/delete

    `/at profile new <existing>` switched to that profile and reset it, then
    printed "Created", so one typed command wiped a profile (R-01). `copy`
    handed AceDB a missing or current name, which raises a raw Lua error in
    the client, and `delete` of a missing name printed a deletion that never
    happened (R-02).

    settings/Slash.lua gains a file-local profileExists(db, name) walking
    db:GetProfiles() for an exact, case-sensitive match. `new` refuses an
    existing name, pointing at `/at profile use` and `/at profile reset`.
    `copy` refuses the current profile ("Cannot copy a profile onto itself")
    and an unknown one ("Profile '<name>' not found — /at profile list shows
    them") before CopyProfile. `delete` keeps its current-profile refusal and
    adds the same not-found line. No pcall. The misleading comment above
    `new` is rewritten; PROFILE_HELP's "Create new profile with defaults" is
    now true. This also meets the LK-03 consumer obligation: kit 26's AceDB
    fake raises on these names, and no raw error reaches a suite or player.

    Tests, red first in tests/test_slashcmds.lua's /at profile section:
    new on an existing Keep (barWidth 333 survives, still on Default), copy
    of a missing name, copy of the current name, delete of a missing name.
    The existing "new creates a profile carrying the defaults" case seeded
    an existing "Fresh" and relied on `new` resetting it; it now makes a
    genuinely new profile from a changed current one and deletes it after.
    The file is 1352 lines, under the 1400 split threshold.

    docs/profiles.md and docs/smoke-tests.md (36a, 38a, 39) document the
    three refusals. docs/test-cases.md regenerated (719 -> 723) and the
    README Tests badge moved to match. The regeneration also restores the
    section signs in three kit test names (localization-§5, line-endings-§5)
    that the committed inventory had lost, so the file matches --list again.

    Findings: AbsorbTracker-R-01, AbsorbTracker-R-02.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube

commit e3d14b13905125351491f897c447487c2f664263
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 07:42:39 2026 +0530

    AT-02: Make slash/profile tests assert real values and clean up per-unit

    The slash and profile tests still addressed the flat barWidth key and the
    removed bar/border pages, left over from before schema v3 made barWidth
    per-unit. That gave nil==nil asserts and cleanups that did nothing, and
    they leaked state into later suites (AbsorbTracker-R-04, testing-§12).

    - tests/test_slashcmds.lua: every RestoreDefaults("bar") / ("border")
      cleanup (:224-225, :371, :552, :574) is now RestoreDefaults("appearance").
      VALID_PAGES is {general, appearance, profiles}, so the old calls reset
      nothing and units.target.barWidth=300 from :218 leaked.
    - /at profile new now seeds units.player.barWidth=456 and asserts
      NS.unitDefaults.barWidth ("-- red under: new that skips
      ResetProfileCounted"). /at profile reset does the same with 478 ("-- red
      under: reset that switches instead of resetting").

    Mutation evidence: with NS.ResetProfileCounted(db) deleted from Slash.lua's
    `new`, the old :545-548 case stayed green. After the rewrite it goes red
    (expected 200, got 456). A `reset` that switches profiles, or skips the
    reset, turns the reset case red. Both mutations were reverted. The case
    count is still 719, and no ordering dependency surfaced.

    Deviations:
    - The profile-new seed is written to an existing "Fresh" profile (switch,
      seed, back to Default), not to Default as the item text says. A
      brand-new AceDB profile starts from defaults whether or not `new` resets
      it, so seeding Default stayed green under the mutation. `new` on an
      existing name is exactly the path the reset exists for.
    - tests/test_schema.lua (outside the item's "test_slashcmds.lua only"): the
      "ApplyDefault is a no-op for a row with no default" case used
      rawSet("barWidth"), which the item's own verify grep must not find. It
      now targets units.player.barWidth and restores to NS.unitDefaults.barWidth.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube

commit aa4c783f344efb1a82b703e1e1e74614306bcc0b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 04:45:03 2026 +0530

    RV-AT: Re-vendor LibKa0s v1.56.0 and record its delta bundle

    Copy LibKa0s/ -> libs/LibKa0s/ and testkit/ -> tests/_kit/ whole from the
    local tag v1.56.0 (tag 4622018 -> commit 514fc0a) via git archive. Both
    diff -r checks against the tag are empty, and the runner stays executable.
    CLAUDE.md's provenance line moves v1.55.0 -> v1.56.0 in the same commit.

    Fifteen library files move a minor: Core 8, Lifecycle 2, Bus 2, Schema 2,
    Item 2, Media 4, Widgets 10, DebugLog 13, Slash 15, Launcher 2, Options 24,
    OptionsWidgets 31, OptionsTabs 4, OptionsScroll 4 and Perf 13. No file is
    added or removed. The kit moves from revision 25 to 26 and adds asserts.lua,
    mock_events.lua and prose_lists.lua.

    The re-vendor bundle docs/revendor/2026-09-23-v1.56.0/ (01_DELTA.md and
    05_SUMMARY.md) was written by hand, following the local wow-addon
    revendor-libka0s procedure as amended by WA-01. Adoption decisions are
    left to this addon's M3 items.

    Green on the copy, so there are no reds to list: luacheck 0/0 in 61
    files, tests 719 passed, 0 failed, lizard 0 warnings, and the largest
    authored file has 1416 lines. AT-01 (460c51d) had already caught the
    Schema stub up to minor 2.
    docs/test-cases.md and the README test badge are not regenerated here; a
    later item owns them. No finding ids. No deviations.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube

commit 460c51d24d8392666c6b5652720012c50dc158d3
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Thu Sep 24 04:39:55 2026 +0530

    AT-01: Catch the Schema degradation stub up to Schema minor 2

    settings/Schema.lua HostSchemaStub() now matches LibKa0s-Schema-1.0
    minor 2 (LibKa0s v1.56.0, docs/api/Schema/version-2-docs.md "The
    degradation stub"), so the re-vendor lands green:

    - S.Set is split into writeRow -> prepareWrite (resolve, validate,
      row.normalize, missing root) -> commit (store + onChange) -> announce.
      prepareWrite keeps Set's refusal arity (false, err, why for a bad
      value; false, err for a missing root). Every Schema.lua function is at
      CCN 8 or below (S.Set was 14).
    - writeThrough: New builds one synthetic { path, writeThrough = true }
      row per listed path; a row-less listed path is stored raw (a copy), with
      no validate/normalize/onChange, and announced with the synthetic row.
      Any other row-less path is still refused. The descriptor is untouched
      here (AT-08 adopts the list).
    - SetMany(entries, opts): all-or-nothing and log-silent; the first
      refusal answers false, err, why, index with nothing stored; then every
      store, every onChange, then announceBatch(writes, rid) once or announce
      per write.
    - S.Get forwards the id to row.get(id); S.ApplyDefault(row, id) forwards
      it to Set.
    - The stub's doc comment cites version-2-docs.md and names SetMany and
      writeThrough.

    Tests: new section "the degradation stub, Schema minor 2" in
    tests/test_schema.lua (9 cases, red first). docs/test-cases.md and the
    README Tests badge regenerated (719). Green on the v1.55.0 payload and on
    a v1.56.0 payload dry run (schema instance parity case passes).

    Finding ids: none (plan item AT-01).

    Deviation: the item has SetMany "commit in order" in phase 2; it runs
    every store first and then every onChange, as the library and the v2
    stub contract specify, so commit() is store()+react() and the batch
    calls the two halves separately. Helpers checkValue, writeRow,
    prepareEntry and announceAll were added to hold the CCN ceiling.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube

commit f4b61a6d7f0bffa0e2c70220b84094df2f39f191
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Wed Sep 23 20:50:31 2026 +0530

    Record the 2026-09-23 review and standards audit

    The frozen docs/reviews/2026-09-23/ and docs/audits/2026-09-23/ bundles
    from the collection-wide sweep. Findings are collated and planned in
    Ka0sAddonsCommonTasks/docs/2026-09-23-REVIEW_AND_STANDARDS_AUDIT_REMEDIATION/.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube

commit 98b4f729c98c58aa78e8b20dab8a7102f4f7ff9c
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Wed Sep 23 19:11:23 2026 +0530

    Bring the module map in line with the v1.55.0 payload

    The vendored LibKa0s now ships fifteen majors across twenty-one files,
    not twelve across eighteen, and its XML loads Compat, Bus and Schema
    after Env. The kit is revision 25, whose prose and layout-cap suites
    took the US-English check out of tests/test_docs.lua; that row now
    names the four rules the file still holds, and tests/prose_waivers.lua
    gets the row it was missing. Four stale line counts are corrected.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx

commit 98b4f729c98c58aa78e8b20dab8a7102f4f7ff9c
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Wed Sep 23 19:11:23 2026 +0530

    Bring the module map in line with the v1.55.0 payload

    The vendored LibKa0s now ships fifteen majors across twenty-one files,
    not twelve across eighteen, and its XML loads Compat, Bus and Schema
    after Env. The kit is revision 25, whose prose and layout-cap suites
    took the US-English check out of tests/test_docs.lua; that row now
    names the four rules the file still holds, and tests/prose_waivers.lua
    gets the row it was missing. Four stale line counts are corrected.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx

commit 7c43ab427e780c7a5612072d8af9ffaa58a7b5f2
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Wed Sep 23 18:55:49 2026 +0530

    Give each unlocked bar the LibKa0s drag handle strip

    While the bars are unlocked each one now gets the strip ConsumableMaster
    shows over its macro bar: LibKa0s-Widgets-1.0's DragHandle, a dark strip
    with a gold edge, the unit's name centered in gold and a help mark on
    the right, anchored above the bar. It replaces bar.unitLabel, which is
    gone with its font plumbing.

    modules/Bar.lua builds one handle per bar (<frame>Handle, moveFrame the
    bar). canDrag asks the lock, and onDragStop saves through the same local
    savePosition the bar body's OnDragStop now uses. The strip's tooltip has
    one body line read off the lock on each hover; the help mark has its own
    tooltip with a /at lock footer. Every string goes through NS.L, and
    enUS.lua lists the keys. The help art comes from NS.Icon("help"), the
    seam's first call site. The bar body keeps its own drag.

    UpdateBarAppearance shows the handle while unlocked, sized with
    ApplyWidth(barWidth), and hides it while locked. The combat re-lock
    hides it too. The default stack now leaves the strip's HEIGHT + GAP
    between bars, so the player bar's strip does not sit over the target
    bar. With the library absent there is no strip, the stack spacing is
    unchanged, and nothing raises. That is the widget's documented
    degradation.

    tests/test_draghandle.lua covers the handle per bar and its spec, shown
    only while unlocked, width, canDrag, the shared save and both tooltips,
    plus the degraded load. The unit-label cases leave test_display.lua and
    its stack test moves to the new spacing. The docs move with it:
    ARCHITECTURE (Widgets now bound by name, the localization row), the
    module map, a rewritten smoke item 68, the test inventory and the
    badge (710).

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx

commit 6416d11da7043e7a738c51682aa47d98a839b4e9
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Wed Sep 23 18:47:44 2026 +0530

    Pin the bar body's drag before the strip lands

    A new suite, tests/test_draghandle.lua, pins the one way to move a bar
    that has to survive the drag-handle change: every bar body is registered
    for OnDragStart/OnDragStop, and a drop saves the position through
    NS.Units.SetPosition to that bar's own unit and to no other. The
    unlocked unit label's show/hide/text cases already sit in
    tests/test_display.lua. Green on the current code; the badge and the
    test-case inventory move to 695.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx

commit 1a410cb1f1ce79defa94d94e6a2e1484c7f6f621
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Wed Sep 23 16:54:31 2026 +0530

    Make the stand-down prose match the guarded UNITS receiver

    The degraded-UNITS test's falsification note said four registrations
    come back without the guard; measured it is five (PLAYER_TARGET_CHANGED,
    and UNIT_ABSORB_AMOUNT_CHANGED and UNIT_MAXHEALTH twice each).

    ARCHITECTURE.md's Message Bus paragraph and "What stands down" bullet
    said no module learns the latch exists, which stopped being true when
    the UNITS receiver began asking NS.IsStoodDown(). Both now say no
    receiver has to ask for its subscription to come down, and name the one
    that asks anyway and why.

    The v1.55.0 revendor summary names the guard by its commit (9e6a4a6)
    and says what it does, in place of "a Phase 6 follow-up".

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx

commit 7b2aef334ac884e89421e36b23c6934ca8ad3ead
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Wed Sep 23 16:50:40 2026 +0530

    Name the v1.55.0 re-vendor bundle for its tag

    audit-review-history requires a re-vendor bundle folder shaped
    <YYYY-MM-DD>-v<tag>. This run's bundle was written to a bare-dated
    folder because the sweep's brief named the wrong path. The folder is
    renamed to 2026-09-23-v1.55.0 and every reference follows it. The
    bundle's contents are unchanged.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx

commit 9e6a4a627484f076c9a3c20398bd314bef3b9bde
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Wed Sep 23 15:44:15 2026 +0530

    Keep the UNITS receiver from re-registering on a stood-down addon

    With LibKa0s missing, core/Bus.lua's untracked-target stub cannot take
    the UNITS subscription down, and its handler called SyncUnitEventFrames
    without asking the latch. A publish while disabled put four per-unit
    RegisterUnitEvent registrations and PLAYER_TARGET_CHANGED back on the
    addon, against slash-commands-7. The receiver now returns while
    NS.IsStoodDown(); StandUp re-syncs from current state, so nothing is
    lost. The live build never reaches the line.

    A degraded-load case in tests/test_bus.lua pins it (red before the
    guard with five registrations back). Known Limitations and the
    2026-09-23 revendor summary stop saying every handler answers to the
    latch; the badge, test-case inventory and module-map rows move with it.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx

commit 368e82f0d70c205418081430d334ff32a54085d8
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Wed Sep 23 15:28:41 2026 +0530

    Record the v1.55.0 adoption run in the revendor bundle

    Steps 5-8 for LibKa0s v1.55.0: the candidates (Bus, Schema, Compat), the
    decisions as they landed under the owner's delegation, the execution plan
    with what actually ran, and the summary with every gate's numbers. Bus
    and Schema were adopted (92c48d8, 0e72839); Compat was declined as never
    and filed as #31.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx

commit 0e72839ff8e2d04caeb4ad486a030e5444dff237
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Wed Sep 23 15:26:44 2026 +0530

    Adopt LibKa0s-Schema-1.0 as the settings schema runtime

    settings/Schema.lua becomes the major's setup file: the library's instance
    over the live NS.Schema array, or the write-completing, log-silent host
    stub when LibKa0s is absent. The host's names are bound to its members
    (SetByPath, FindSchemaRow, RegisterSchemaRows, ApplyDefault, Bulk,
    ResolvePath/SetPath, the reset count trio, ValidateSchema), so no
    production call site moved. The console and minimap rows carry their own
    get/set, stamped by settings/General.lua; NS.GetSetting is the runtime's
    read with the shipped defaults behind it, and NS.SetSetting is gone. The
    minimap sweep exemption is the runtime's resetExempt.

    Characterization first: the write's order (store, [Set] line, onChange)
    and the three degraded writers (the lock verbs, the combat re-lock, Reset
    All) landing in the store. Pinned with the change: an unknown path is
    refused and a table value is stored as a copy (the API document's
    adoption notes); the degraded Reset All's debug lines re-pin to "the
    write landed, the line is absent"; the stub's lib and instance parity;
    the minimap row surviving a sweep. Raw fixture writes in the suites go
    through the harness's rawSet. tests/perf.lua stays under its ceilings.
    Test inventory and README badge move to 691.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx

commit 92c48d8eed7728123f143392a85d8f5b85bc3933
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Wed Sep 23 15:11:29 2026 +0530

    Adopt LibKa0s-Bus-1.0 for the bus record and the message catalog

    core/Bus.lua's hand-written subscription register gives way to the
    library's stand-down record: NS.NewBusTarget hands out tracked targets,
    the latch calls NS.BusStandDown last and NS.BusStandUp first, and the five
    subscription sites register on their targets directly. NS.MSG is declared
    through Bus.Catalog, so an undeclared key now raises for a publisher too.
    With LibKa0s absent the untracked-target stub keeps each receiver on a
    private target and records nothing; Known Limitations says so.

    Characterization first (the five bus pairs by name through a full
    disable/enable, and each consumer reached once after it), then the stub's
    parity by name, the degraded load, the strict read, and the two record
    properties the old register lacked. The surface-source map gains the Bus
    row. Test inventory and README badge move to 683.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx

commit d5e37d6b35478684274e2419a90dbf7679053cdc
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Wed Sep 23 14:57:30 2026 +0530

    Move the README test badge to the 674 the inventory now reports

    27ccce6 regenerated docs/test-cases.md to a 674 total but left the badge
    at 646. documentation-§1 and testing-§5 require the badge to move in the
    same change as the inventory, so this is a same-change miss landed as the
    next commit rather than folded back.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx

commit 27ccce69206740dc12fd87e47e0bfb92c1dfc164
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Wed Sep 23 14:53:29 2026 +0530

    Re-vendor LibKa0s v1.55.0

    Both payloads copied whole from the tag: three new majors (Compat, Bus,
    Schema) and their LibKa0s.xml rows, every existing file's minor unchanged,
    and test-kit revision 25. The provenance line moves in the same commit.
    The runner declares the kit's new layout-cap gate by its (basename,
    directory) pair. No contract blockers; nothing adopted yet. The delta is
    recorded in docs/revendor/2026-09-23/01_DELTA.md and the test-case
    inventory is regenerated.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx

commit b6360c9a2f4e4a2c5e99f562e0debbc339a0da27
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Wed Sep 23 14:50:23 2026 +0530

    Add the layout-§1 census heading under the deviations register

    Nothing is over the 1500-line cap today; the census says so as a result,
    ahead of the kit revision 25 gate that reads it.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx

commit 35f92ea987a62d2537ba7c367fe40892e34832b5
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Wed Sep 23 11:34:17 2026 +0530

    Re-vendor the standard reference to v2.63.0: .gitattributes to the canonical body

    The standards sweep against Ka0s WoW Addon Standard v2.63.0 found one item
    to apply in this repo. .gitattributes now matches line-endings-§5's
    client-bound canonical body byte-for-byte: the shebang carve-out comment is
    the current wording and `*.py text eol=lf` joins `*.sh text eol=lf`. The pin
    (`* text=auto eol=crlf`) and the binary block are unchanged, the repo tracks
    no .py file, and the worktree straggler count is 0 before and after, so no
    renormalization rides along.

    Everything else already conforms: the three-place reference (TOC
    X-Standard, bare README badge, CLAUDE.md "Standards compliance"), zero
    retired dotted notation outside frozen bundles, every filename-§N citation
    in range, and the gate statements in docs/testing.md and
    docs/automated-tests/README.md already name both checkpoints.

    Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx

commit 7cfb3472169f6462b3842e4d044f5462cebdef96
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Tue Sep 22 21:04:19 2026 +0530

    Adopt the kit's US-English gate, and delete the copy this repo was keeping

    LibKa0s v1.54.2 re-vendored, both payloads whole. The library bytes are identical to v1.53.0 --
    kit revision 24 changes no library file -- so what actually arrives here is tests/_kit/test_prose.lua
    and one line in tests/run.lua declaring it.

    WHAT CAME OUT IS THE POINT. localization-5 says wire the kit's gate or your own and never both,
    because two gates over one rule is two copies of a list each required to be carried WHOLE. So the
    hand-written one goes: seven repositories in this collection had written that gate themselves under
    three different filenames, which is why nothing could tell at a glance which repositories had one.

    COVERAGE WENT UP ON THE SWAP, which is why this is not a lateral move. The hand-written gates
    walked a glob of the addon's own source. The kit's reads the tracked set out of git, so the TOC,
    the docs, the locale files and .luacheckrc are held to the same rule -- and its exclusions are a
    named list rather than whatever a glob happened to miss. Everything the sweep corrects below was
    invisible to the gate that was here yesterday.

    WHERE A SPELLING IS NOT THIS REPO'S ENGLISH TO CORRECT it goes in tests/prose_waivers.lua, per FILE
    and per WORD, with the reason beside it -- never per file alone, which would hide every other
    British spelling in a file this repo edits often. A waiver is a debt where it stands in for work
    that is owed, and it says so.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk

commit 5e661644227fb528c21b20a991c31be3c9c49e0d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Tue Sep 22 19:38:20 2026 +0530

    Close out the documentation drift the sync pass reported but could not act on

    The sync run surfaced every hit its own rules fenced it away from: comment citations, which need a
    named replacement rather than a guessed one; count claims it could see but not settle; residual
    British spellings; and one root doc that was genuinely owed. This is that list worked through, each
    item either corrected against evidence in the tree or left alone with the reason recorded.

    A comment naming a file that is gone is not automatically wrong. Most of them name the absent thing
    ON PURPOSE -- "it used to be ours", "which is why that file is gone rather than emptied", "has not
    existed since debug logging moved to LibKa0s" -- and correcting those would delete the explanation
    they exist to give. They were read individually and left. What was corrected is the other kind: a
    citation whose target moved, a count that no longer counts, a claim the cited line does not support.

    Nothing that runs was touched. No version string moved, no export was deleted, no generated doc was
    hand-edited, and the vendored payloads are untouched. Every correction was re-checked against the
    code by a pass that did not write it, and the green gate was re-run from scratch afterwards.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk

commit a5d3e22ac07c48238fefb63ac55cea3144b8cb6e
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Tue Sep 22 18:05:55 2026 +0530

    Sync the docs to what the code actually does

    A /wow-addon:sync-docs pass over the whole collection, each repo's drift found against its own
    source and each correction carrying the evidence that settled it: a count re-counted, a file:line
    re-grepped, a load order read back off the TOC, a doc-map row checked against the directory in both
    directions.

    Documentation only. No version string moved, nothing under libs/ or tests/_kit/ was touched, and no
    comment was edited -- the comment-citation check ran and its hits are reported rather than applied,
    because that correction needs a named replacement and there was nobody to name one. Dead exports and
    missing Tier 1 docs are likewise surfaced, not acted on.

    Every claim added or changed here was re-verified against the code by a second pass that had not
    written it, and the green gate was re-run from scratch afterwards: several suites in this collection
    read the docs, so a documentation edit can and does turn them red.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk

commit ca833c4dc7d2c5ee060945f6a0438f8d65ea7113
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Tue Sep 22 17:11:29 2026 +0530

    Re-vendor LibKa0s v1.53.0

    OptionsWidgets minor 30 (LibKa0s-Options-1.0 23.30.3.7.3); every other file
    unchanged from v1.52.0, kit at revision 23. Payload taken from the v1.53.0 tag
    and verified identical, and the provenance line in CLAUDE.md moves with the
    bytes rather than after them.

    O.IdInput's Add button is now the height of the edit box beside it. It was
    never mis-anchored -- AceGUI's labeled EditBox publishes alignoffset = 30 and
    Flow honors it, so the two centers were one pixel apart. The button was 24 tall
    against InputBoxTemplate's 20-tall border art, so it overhung 2px at each end,
    and the overhangs do not read alike: the top one sits against the row's gold
    caption and the bottom against empty dark, which is what reads as "higher".

    Nothing to adopt: no new member, no new field.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk

commit a39a540045a4dc22debb5cd85dd6543c901a0701
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Tue Sep 22 10:21:17 2026 +0530

    Re-vendor LibKa0s v1.52.0

    Both payloads copied whole from the v1.52.0 tag -- libs/LibKa0s/ and
    tests/_kit/ -- and the CLAUDE.md provenance line rolled in the same
    commit, from v1.51.0.

    Minor 29 is mostly a fix to the library's own v1.51.0: the O.IdList help
    mark reserved too little of the row for its absolute frame, so the column
    fit correctly collapsed every list that adopted `help` to one column.
    This addon adopts none of the help surface, so nothing here changes.

    Gate: lint 0 warnings / 0 errors in 59 files; 646 passed, 0 failed, 0 skipped, 646 total

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk

commit ee09708e9f599a79fe19363f89fba4b3745f8e72
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Tue Sep 22 02:23:29 2026 +0530

    Re-vendor LibKa0s v1.51.0

    Both payloads copied whole from the v1.51.0 tag -- libs/LibKa0s/ and
    tests/_kit/ -- and the CLAUDE.md provenance line rolled in the same
    commit, from v1.50.0.

    Minor 28 adds three OPTIONAL O.IdList spec fields (entry.help,
    spec.helpIcon, kind.suggestTag) which this addon does not use, and one
    behaviour change that arrives without being asked for: every id-list row
    lights under the cursor now, not only above one column.

    Gate: lint 0 warnings / 0 errors in 59 files; 646 passed, 0 failed, 0 skipped, 646 total

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk

commit 5ce09cb44048dcf310b3efd22a1fe7f447b0ec80
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Mon Sep 21 14:47:47 2026 +0530

    Re-vendor LibKa0s v1.50.0

    Both payloads copied whole from the v1.50.0 tag -- libs/LibKa0s/ and
    tests/_kit/ -- and the CLAUDE.md provenance line rolled in the same
    commit. The kit stays at revision 23, so tests/_kit/ is unchanged.

    Carries v1.47.0 through v1.50.0 in one step, which is where this repo's
    master had fallen behind. No surface this addon uses changed, so there is
    nothing to adopt: v1.50.0's member manifest is identical to minor 26's,
    and the majors this addon consumes are otherwise untouched.

    Gate: lint 0/0 in 59 files, 646 tests 0 failed.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk

commit 9d9dfde8f4fe993f351926fc7e32e19e03ecc5e9
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Sep 20 19:55:35 2026 +0530

    Re-vendor LibKa0s v1.47.0

    LibKa0s v1.47.0 is Options widgets minor 24: O.IdList gains an optional
    `columns` spec field that packs entries row-major, default 1 and unchanged
    behaviour. Both payloads moved whole -- libs/LibKa0s/ and tests/_kit/ -- and
    CLAUDE.md's provenance line rolled in the same commit, which is what the
    vendor-sync gate reads. Only libs/LibKa0s/OptionsWidgets.lua actually differs;
    the kit stays at revision 23, so no case name moved and docs/test-cases.md
    still counts 646.

    The two-column option is DECLINED here, and there is nothing to decline it on:
    this addon has no O.IdList / H.IdList call site at all. It tracks absorb totals
    for player, target and focus -- there is no spell-id list, no whitelist and no
    per-id store anywhere in settings/, defaults/, modules/ or core/. The only
    mention of the member is the inert degraded-build stub in
    settings/OptionsSetup.lua, carried because the owner asked for the LibKa0s
    v1.35.0 render-time members on every consumer's stub, and the exemption
    tests/test_surface_parity.lua already records for exactly that reason. A stub
    takes no spec, so `columns` reaches nothing. No test was added: a pin on
    row-major order needs a list to pin it to.

    Green through the bounded runner: lua tests/run.lua 646/646, luacheck 0/0 over
    59 files.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk

commit 9d9dfde8f4fe993f351926fc7e32e19e03ecc5e9
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Sep 20 19:55:35 2026 +0530

    Re-vendor LibKa0s v1.47.0

    LibKa0s v1.47.0 is Options widgets minor 24: O.IdList gains an optional
    `columns` spec field that packs entries row-major, default 1 and unchanged
    behaviour. Both payloads moved whole -- libs/LibKa0s/ and tests/_kit/ -- and
    CLAUDE.md's provenance line rolled in the same commit, which is what the
    vendor-sync gate reads. Only libs/LibKa0s/OptionsWidgets.lua actually differs;
    the kit stays at revision 23, so no case name moved and docs/test-cases.md
    still counts 646.

    The two-column option is DECLINED here, and there is nothing to decline it on:
    this addon has no O.IdList / H.IdList call site at all. It tracks absorb totals
    for player, target and focus -- there is no spell-id list, no whitelist and no
    per-id store anywhere in settings/, defaults/, modules/ or core/. The only
    mention of the member is the inert degraded-build stub in
    settings/OptionsSetup.lua, carried because the owner asked for the LibKa0s
    v1.35.0 render-time members on every consumer's stub, and the exemption
    tests/test_surface_parity.lua already records for exactly that reason. A stub
    takes no spec, so `columns` reaches nothing. No test was added: a pin on
    row-major order needs a list to pin it to.

    Green through the bounded runner: lua tests/run.lua 646/646, luacheck 0/0 over
    59 files.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk

commit 34a81208d16cc4c6aff3b5b3a97d9877ef0a2336
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Sep 20 02:36:39 2026 +0530

    CLAUDE.md is the documentation-§2 stub; what only it said moves into docs/

    Root CLAUDE.md had grown past the stub documentation-§2 describes: a docs-set
    essay, working rules, and a long LibKa0s section. It is now the H1, the
    adherence line, the canonical Standards compliance block, the read-the-docs
    pointers, the green-gate line and the provenance line.

    What was recorded nowhere else moved to its standard home:
    - docs/ARCHITECTURE.md: the root-docs trio and the no-agent-context.md rule
      (with the frozen-history note) under Documentation map; the seam-symmetry
      invariant, with the load-completing OptionsSetup stub and loadDegraded().
    - docs/testing.md: the provenance line as a gate input and its README history;
      the whole-folder rule (Perf minor 12 needs Lifecycle); the never-edit rule
      for libs/LibKa0s/ and tests/_kit/ and their exclude_files; CRLF on disk, the
      two WSL mirror paths and the LF-to-CRLF sed.
    - docs/common-tasks.md: Working conventions (terse replies, file_path:line,
      why-only comments, no unrequested docs).

    Content already in docs (the module list, the nine seams, NEEDS_WIDGETS, luac
    -p, the test-case inventory and badge rule) was dropped from CLAUDE.md. The
    module-map.md top-level-docs line and a tests/test_ltrap.lua comment that
    pointed at the removed CLAUDE.md section now point at the new homes.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01WkU3isSkvWPZkWVr51uZKo

commit cc6af608253f8764e52bf2b1e56d15cea236c24d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Sep 20 02:33:25 2026 +0530

    Comments follow the v1.46.1 combat lock and stop citing TOC line numbers

    settings/Appearance.lua still said the library refuses to draw in combat and
    closes the Settings window first. Since LibKa0s v1.46.1 a page shown in combat
    is covered and draws nothing until PLAYER_REGEN_ENABLED, writes, Defaults and
    tab switches are refused, and the window is never closed; the comment now says
    so, matching the General.lua and Profiles.lua rewording in e510db6.

    settings/OptionsSetup.lua, docs/common-tasks.md and docs/module-map.md cited
    AbsorbTracker.toc :29 (widget.xml) and :65 (OptionsSetup.lua), which had
    drifted to 31 and 75. They now name the TOC entries instead of line numbers.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01WkU3isSkvWPZkWVr51uZKo

commit 22e97542aa3fabffde3be0a78358163f703ac697
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Sep 20 02:17:17 2026 +0530

    Docs catch up with the Lifecycle and Launcher majors and the v5 ladder step

    The seam paragraph in ARCHITECTURE.md still counted four setup files and
    five descriptor-taking majors; Lifecycle and Launcher make it six and seven,
    nine majors bound of the twelve vendored. module-map.md and performance.md
    said eleven majors across sixteen files and left Lifecycle out of the load
    order and OptionsTabs out of the Options file list.

    Also: the Database row gains the { to = 5 } step, data-flow.md counts four
    ladder rows, profiles.md gives the account-wide stamp's real default (1, not
    4) and why, the kit row reads revision 23 with mock_record.lua and current
    line counts, Bar.lua's row records the bars being created hidden, the
    test_widgets row names the sidebar combat-lock case, and settings-panel.md
    says combat lock where it still said refusal.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01WkU3isSkvWPZkWVr51uZKo

commit e510db651d25f287a9c9c5d3442d2449dba85f57
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 19 21:52:27 2026 +0530

    Re-vendor LibKa0s v1.46.1

    LibKa0s v1.46.1 implements the standard v2.60.0 combat lock (options-ui-§2/§13,
    anti-pattern #88). A settings page shown in combat is no longer closed: it is
    covered (ctx.__combatCover), nothing renders, one gray COMBAT_LOCKED_NOTICE line
    is printed per combat, and writes, Defaults and tab switches are refused until
    PLAYER_REGEN_ENABLED, which draws the page from current state. The library
    registers PLAYER_REGEN_* only while one of its pages is on screen
    (lib.__shownPages). /at config still refuses in combat with COMBAT_REFUSED.
    Kit stays at revision 23.

    Host test changes:
    - tests/test_widgets.lua: the sidebar combat test now asserts the new
      behaviour for General and Appearance -- each page is covered, draws nothing
      on a show in combat, the Settings window is not closed (no
      SettingsPanel:Close, no HideUIPanel), and exactly one COMBAT_LOCKED_NOTICE
      line is printed across both shows. It hides the pages afterwards.
    - tests/test_disabled.lua: bringUp() closes every page an earlier suite left
      on screen before taking its baseline, so the library's own PLAYER_REGEN_*
      watch is not counted as an addon registration the stand-down must remove.

    Docs and comments that described the old close-the-window refusal now describe
    the combat lock (settings-panel.md, smoke-tests.md 13a, common-tasks.md,
    module-map.md, settings/*.lua); docs/test-cases.md regenerated (646 cases).

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01WkU3isSkvWPZkWVr51uZKo

commit e510db651d25f287a9c9c5d3442d2449dba85f57
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Sep 19 21:52:27 2026 +0530

    Re-vendor LibKa0s v1.46.1

    LibKa0s v1.46.1 implements the standard v2.60.0 combat lock (options-ui-§2/§13,
    anti-pattern #88). A settings page shown in combat is no longer closed: it is
    covered (ctx.__combatCover), nothing renders, one gray COMBAT_LOCKED_NOTICE line
    is printed per combat, and writes, Defaults and tab switches are refused until
    PLAYER_REGEN_ENABLED, which draws the page from current state. The library
    registers PLAYER_REGEN_* only while one of its pages is on screen
    (lib.__shownPages). /at config still refuses in combat with COMBAT_REFUSED.
    Kit stays at revision 23.

    Host test changes:
    - tests/test_widgets.lua: the sidebar combat test now asserts the new
      behaviour for General and Appearance -- each page is covered, draws nothing
      on a show in combat, the Settings window is not closed (no
      SettingsPanel:Close, no HideUIPanel), and exactly one COMBAT_LOCKED_NOTICE
      line is printed across both shows. It hides the pages afterwards.
    - tests/test_disabled.lua: bringUp() closes every page an earlier suite left
      on screen before taking its baseline, so the library's own PLAYER_REGEN_*
      watch is not counted as an addon registration the stand-down must remove.

    Docs and comments that described the old close-the-window refusal now describe
    the combat lock (settings-panel.md, smoke-tests.md 13a, common-tasks.md,
    module-map.md, settings/*.lua); docs/test-cases.md regenerated (646 cases).

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01WkU3isSkvWPZkWVr51uZKo