1.2.0-release
What's new
commit 528ee29750771843400a2befdd130411e9ca9275
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 03:22:50 2026 +0530
Automated tests after the Artwork splits (20260927-032003)
Verdict green at 8cda106. Lint 0/0 over 68 files (66 -> 68, the two new
split files); tests 964 passed / 0 skipped / 964, unchanged, name for name;
perf skip (no tests/perf.lua); complexity 16138 NLOC / 1917 functions,
avg NLOC 7.4, avg CCN 2.0, max CCN 15, 0 warnings.
modules/Artwork.lua and tests/test_artwork.lua are out of the 1000-1500
band, which drops from 3 files to 1; only tests/test_libka0s.lua (1131)
remains, and its RESULTS.md disposition is refreshed to this run.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 8cda106b5096fa627e36ab68a3735a23206a41e2
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 03:18:58 2026 +0530
Split tests/test_artwork.lua: the single-texture geometry sections move to tests/test_artwork_geometry.lua
A move along the same catalog / geometry seam as modules/Artwork.lua, with
no case changed. The Fill (FIT, FILL, STATIC, STRETCH, TILE), Resize,
Position, UV composition, Color and Degenerate input sections move whole,
with the panel x art matrix and the uv helpers only they use (PANELS, ARTS,
forEachCombo, specFor, cropOf, assertUV). The small fixtures both halves
need (record, the seed row, withRows, withArt) are restated in the new
suite so each stays loadable on its own. tests/test_artwork.lua keeps the
Catalog, Upgrade inertness, Persistence, Renderer and Composite sections.
tests/run.lua lists the new suite straight after test_artwork.
Line counts: tests/test_artwork.lua 1356 -> 738;
tests/test_artwork_geometry.lua 0 -> 670.
Test cases: 964 before, 964 after, and the sorted `lua tests/run.lua --list`
names are identical; test_artwork 98 -> 46, test_artwork_geometry 52.
luacheck 0 warnings / 0 errors; lizard -C 15 -w 0 warnings.
Ripple: docs/test-cases.md regenerated with --list, docs/module-map.md
(new row, test_artwork row narrowed), docs/ARCHITECTURE.md (census and band
prose) and the Disposition cell of this file's row in
docs/automated-tests/RESULTS.md.
anti-pattern #53: Accepted at three release runs (1.0.0, 1.1.0, 1.2.0).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit bca7fabdbfda3db9e95b951d9e54eeb64c187b5c
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 03:16:25 2026 +0530
Split modules/Artwork.lua: the geometry moves to modules/ArtworkGeometry.lua
A move along the catalog / geometry seam, with no behavior change.
modules/Artwork.lua keeps the generated catalog, CUSTOM_NATIVE_SIZE,
MAX_ART_QUADS and the lookups (Entry, List and the record resolver).
BuildArtSpec, NativeSize, the fill matrix, UV composition and composite
slicing move whole to modules/ArtworkGeometry.lua, which extends the same
NS.Artwork table. The one local the geometry reached across the seam,
resolve, is published as Artwork.__resolve, following the double-underscore
seam convention settings/PanelEditor.lua uses, and read at call time. The
TOC loads the new file straight after modules/Artwork.lua, ahead of Canvas.
tools/artwork/update_catalog.py still targets modules/Artwork.lua.
Line counts: modules/Artwork.lua 1188 -> 693; modules/ArtworkGeometry.lua
0 -> 518.
Test cases: 964 before, 964 after (lua tests/run.lua, 0 failed);
luacheck 0 warnings / 0 errors; lizard -C 15 -w 0 warnings.
Ripple: docs/module-map.md (new row), docs/ARCHITECTURE.md (census and
band prose), docs/rendering.md, docs/common-tasks.md, docs/smoke-tests.md,
the two code comments in modules/Canvas.lua and modules/SunnArt.lua that
name where the geometry lives, and the Disposition cell of this file's row
in docs/automated-tests/RESULTS.md.
anti-pattern #53: Accepted at three release runs (1.0.0, 1.1.0, 1.2.0).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 3173f1cf179a4eba52d543f69ee01b7ab84a3589
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 03:09:02 2026 +0530
Release 1.2.0: version bump, release notes and the gated release run
Version 1.1.1 -> 1.2.0 (owner-approved minor).
Release gate, read from docs/automated-tests/20260927-030403/manifest.json
(run with --release 1.2.0 on the clean tree at 83e958f):
- Lint: PASS, 0 warnings / 0 errors in 66 files
- Tests: PASS, 964 passed, 0 failed, 0 skipped of 964
- Perf: PASS by the no-scenarios exception; the addon ships no
tests/perf.lua, so perf was skipped, not measured
- Complexity: PASS, lizard 1.24.0 ran; 16108 NLOC, 1915 functions,
avg CCN 2.0
- CCN <= 15: PASS, 0 warnings, max CCN 15
Files:
- PanelMaster.toc: ## Version 1.2.0
- core/Namespace.lua: NS.version = "1.2.0"
- core/Database.lua: the [Init] summary example comment reads v1.2.0
- docs/smoke-tests.md: /pm version, /pm help header and the TOC-vs-constant
smoke case read 1.2.0
- README.md: new 1.2.0 row at the top of Version History (bulleted
highlights, de-AI pass run, plus the perf-skip note); old rows untouched
- docs/automated-tests/20260927-030403/: the release bundle, with its
ANALYSIS.md
- docs/automated-tests/RESULTS.md: the runner's row, plus refreshed
watch-list dispositions. modules/Artwork.lua and tests/test_artwork.lua
have now been Accepted across three consecutive release runs and are
owed a fix or a tracking issue (anti-pattern #53).
Left alone: the CLAUDE.md LibKa0s provenance (v1.62.0, the vendored tag),
the auto-derived CurseForge badge, and the 1.1.1 history row.
docs/test-cases.md did not change. Post-edit harness re-run: 964/964 pass,
lint 0/0.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 83e958f1f7ba649a8a255b96f4455a4225727770
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 03:03:50 2026 +0530
README: Usage as the four-step panel setup, and sync-docs
- README Usage is restructured as the four steps of setting up a panel.
- "How panels work" now opens on frame strata and corrects the claim about
mouse handling.
- sync-docs: refreshed file:line citations in DEPENDENCIES.md,
docs/compat-layer.md, docs/media.md, docs/performance.md and docs/testing.md.
- core/Database.lua: the frame-name backfill citation now points at
modules/Registry.lua:205-207 (was :204-206); comment-only.
Green gate: lua tests/run.lua 964 passed / 0 failed; luacheck 0 warnings / 0 errors.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit d11eb877f9c02796d3efd6d2f3e9ae7164e99e8a
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 02:28:34 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), beside the artwork credit. 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 3feaf3d437d9cc4ffcb7993641d0bc23fd1927e7
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 00:15:50 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 61c3b954940c9edcfcda4d008f54a586a071ed00
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 23:03:29 2026 +0530
PM-ATS-SDR: Correct stale comment citations (owner-approved sync-docs follow-up)
Comment-only citation fixes after the PM-ATS-02 peel of the editor's tabs
into settings/PanelEditorTabs.lua:
- core/Constants.lua:23 - the `label` reader is settings/PanelEditorTabs.lua
(opt.label at :182), not settings/PanelEditor.lua.
- core/CoreSetup.lua:8,20-22 - printer-upvalue list gains
settings/PanelEditorTabs.lua (:5 `local print = NS.Print`); five -> six.
- tests/test_schema.lua:315 - EDITOR_TABS is defined in
settings/PanelEditorTabs.lua:73.
- tests/wow_mock.lua:386 - buildPanelEditor is defined in
settings/PanelEditorTabs.lua:113.
- tests/test_options_groups.lua:3 - the suite scans
settings/PanelEditorTabs.lua (EDITOR at :39), where the blocks are drawn.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 61c3b954940c9edcfcda4d008f54a586a071ed00
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 23:03:29 2026 +0530
PM-ATS-SDR: Correct stale comment citations (owner-approved sync-docs follow-up)
Comment-only citation fixes after the PM-ATS-02 peel of the editor's tabs
into settings/PanelEditorTabs.lua:
- core/Constants.lua:23 - the `label` reader is settings/PanelEditorTabs.lua
(opt.label at :182), not settings/PanelEditor.lua.
- core/CoreSetup.lua:8,20-22 - printer-upvalue list gains
settings/PanelEditorTabs.lua (:5 `local print = NS.Print`); five -> six.
- tests/test_schema.lua:315 - EDITOR_TABS is defined in
settings/PanelEditorTabs.lua:73.
- tests/wow_mock.lua:386 - buildPanelEditor is defined in
settings/PanelEditorTabs.lua:113.
- tests/test_options_groups.lua:3 - the suite scans
settings/PanelEditorTabs.lua (EDITOR at :39), where the blocks are drawn.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 76d4bd9db43e82e83bc908e9485ac79dafbd6f9d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 19:45:58 2026 +0530
PM-ATS-SD: Sync docs to the tree after the automated-tests sweep
- docs/testing.md: the linter's scoped file count is 66, not 61 (two places;
the PM-ATS-01/02 peels added tests/test_panels_page.lua and
settings/PanelEditorTabs.lua).
- docs/module-map.md: six files take NS.Print as a file-scope upvalue, not
five; settings/PanelEditorTabs.lua:5 is the new one.
- docs/ARCHITECTURE.md: the events-frames-taint-§8 deviation row names
settings/PanelEditorTabs.lua among the files with pre-formatted print
lines (PanelEditorTabs.lua:632).
- docs/common-tasks.md: the Panels page draws its strip in
settings/PanelEditor.lua and dispatches on ctx.activeTab in
settings/PanelEditorTabs.lua (:785).
docs/test-cases.md regenerates byte-identical (964 cases). README.md,
CLAUDE.md and DEPENDENCIES.md unchanged. Five stale source/test comment
citations are reported for owner confirmation, not edited.
Gate: lua tests/run.lua 964 passed / 0 failed; lint 0 warnings / 0 errors
in 66 files.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 7c46ae66075044b95964a644489115fc215d587e
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 19:33:11 2026 +0530
PM-ATS-99: Final automated-tests sweep run (20260926-193106)
The closing four-suite run of the 2026-09-26 automated-tests sweep, at
5119ae1 on a clean tree. Verdict green.
- lint: 0 warnings / 0 errors in 66 files (64 at 20260926-160448; the two
peel targets are new files)
- tests: 964 passed, 0 skipped, 0 failed of 964 (unchanged; PM-ATS-01
moved cases between suites)
- perf: skip, no tests/perf.lua (unchanged)
- complexity: 16108 NLOC / 1915 functions (+50 / +1), avg NLOC 7.4, avg
CCN 2.0, max CCN 15, avg tokens 58.0, 0 warnings (all unchanged)
Compared with 20260926-160448, the 1000-1500 band went from 5 files to 3.
tests/test_panel.lua (1491) and settings/PanelEditor.lua (1464) left it
through PM-ATS-01 and PM-ATS-02 and are now 721 and 746 lines. Nothing
crossed into the band and nothing is over the cap. The three dispositions
carried forward keep their rulings, updated to today's figures (ATS-23).
ANALYSIS.md is written in CRLF, as .gitattributes requires.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 5119ae11afc150de1fab9ad58135b97e108c5e8c
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 19:02:20 2026 +0530
PM-ATS-02: Peel the editor's six tabs out of settings/PanelEditor.lua into settings/PanelEditorTabs.lua
ATS-10 (automated-tests sweep 2026-09-26): settings/PanelEditor.lua stood at
1464 lines, 36 under the layout-§1 cap, with its split already tracked as #47.
The cut is the page / tab-content seam #47 verified. What each tab holds
moved whole, unchanged, into settings/PanelEditorTabs.lua (798): the TAB_*
names, EDITOR_TABS / E.TABS / IS_EDITOR_TAB, the editor's vertical-rhythm
constants and buildPanelEditor. settings/PanelEditor.lua (1464 -> 746) keeps
the page: the selection, the mutation actions, the control kit the tabs draw
with, the strip, the chrome band, the rebuilder and the bus.
No behavior change. The two halves share through NS.PanelEditor, bound on first
use the way both already bind settings/Panel.lua's NS.Panel.__ui helpers, so
the files may load in either order: the page publishes its kit as
E.__controls (editorRow, editorSpacer, editorHeading, addRefresher and the
media, color-pair and edge makers) and the tabs file reaches the page's
existing E.__pageActions / E.__panelsByName; the tabs file publishes
E.__editorTabs (EDITOR_TABS, IS_EDITOR_TAB, buildPanelEditor) back.
buildPanelEditor binds at its first statement. makePairButton and
BUTTON_PAIR_REL move to the tabs file's binder, the only file that uses them.
The TOC gains settings\PanelEditorTabs.lua after PanelEditor.lua, before
Panel.lua, with its load-order comment. The four source-scanning cases follow
the code: the numberField bounds scan and the options-ui-§16 block gate read
the tabs file, and the NS.Debug-gate and disabledIf scans cover both files.
Tests: 964 cases before and after, same names in the same order. Docs:
module-map row for the new file, ARCHITECTURE.md census, settings-panel.md,
smoke-tests.md, compat-layer.md line references, and the RESULTS.md watch-list
disposition.
Fixes #47
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 9bfd6a83ac20d40040a6387d609663d4a2e13e5b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 18:52:25 2026 +0530
PM-ATS-01: Peel the built Panels page's cases out of tests/test_panel.lua into tests/test_panels_page.lua
ATS-05: tests/test_panel.lua had grown to 1491 lines, past its re-check-at-1400
trigger and 9 lines under the layout-§1 cap. It splits on its own seam, the
"Panels page's tab strip" block: those 18 cases drive the real E:BuildPage /
E:Rebuild against the AceGUI mock through their own helpers (freshPanelsCtx,
labelsBuiltBy, descendants, captionsBuiltBy, actsOnGeneral) and reach none of
the head's locals (fakeCtx, pctx, watch, freshPanels, R/Canvas/PC).
- tests/test_panel.lua 1491 -> 721 (65 -> 47 cases): registration, opening,
Defaults, the repaint policy, panel scale.
- tests/test_panels_page.lua new, 780 (18 cases): tab strip, chrome band,
editor tabs, swatches. Moved verbatim; only the two comments that said
"above" now name tests/test_panel.lua.
- tests/run.lua lists it straight after test_panel, so the PASS lines run in
the identical order (diffed): 964 total before and after.
- docs/test-cases.md regenerated; module-map, testing.md (swatch case), the
ARCHITECTURE.md band census and largest-file line, and the RESULTS.md
watch-list disposition updated.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 8b7a45493350db00fa7d6915a7a7d385d89c0c1b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 18:45:45 2026 +0530
PM-ATS-RVR: Restore CRLF working copies of four v1.62.0 revendor bundle files
docs/revendor/2026-09-26-v1.62.0/01_DELTA.md, 02_CANDIDATES.md,
03_DECISIONS.md and 05_SUMMARY.md sat on disk as bare LF while
.gitattributes pins them to eol=crlf, which failed the eol test
(963 passed / 1 failed). Each was removed and re-checked out from the
index; CR count now equals LF count in all four (65/65, 6/6, 5/5,
15/15). The index copies were already LF, so the committed content is
unchanged and this commit is empty; it records the fix.
Green gate (bounded): lua tests/run.lua 964 passed / 0 failed / 964
total; 0 warnings / 0 errors in 64 files from the linter; no function
above CCN 15 from the complexity check.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 84b25be0867541c0d31ad6cdd55d63e59e13365a
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 18:42:34 2026 +0530
PM-ATS-RV: Re-vendor LibKa0s v1.62.0 and kit revision 31
Both payloads come from the local v1.62.0 tag (e660362), whole folders. libs/LibKa0s: Options 25 -> 26, OptionsWidgets 31 -> 32, OptionsTabs 5 -> 6, and the four peeled files OptionsRegistry, OptionsIds, OptionsIdList and OptionsCombat at minor 1 (Options key 26.1.32.1.1.6.1.7.4.1). tests/_kit: kit revision 27 -> 31, with the new inventory.lua, prose_coverage.lua and prose_selftests.lua. The kit carries the runner fixes for ATS-20 (None. under an empty watch-list table in RESULTS.md) and ATS-21 (generated files left out of the band table). The CLAUDE.md provenance line rolls with the bytes.
No member, descriptor field or row field changed upstream, so the library-absent stub and the surface-parity case need nothing, and no hand-typed library list here names the moved files. docs/test-cases.md regenerated with --list is byte-identical (964 cases). Bundle docs/revendor/2026-09-26-v1.62.0/ records the delta; no adoption in this item.
Gate: 964 passed / 0 failed (964 before), luacheck 0/0 in 64 files, lizard no function above CCN 15, vendor gate clean against the tag and ../LibKa0s.
ATS-20, ATS-21
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 12b1c61cfd3a76eac0a14ea997e753949de6dcfd
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 16:19:30 2026 +0530
PM-ATS-00: Record the 2026-09-26 automated-tests sweep run (20260926-160448)
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 73d9b8b8670f0cc754ca91e7b126e444662a2eb8
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 15:33:02 2026 +0530
Docs: record the owner's in-client results for the settings layout
The owner ran this build's checks in the client on 2026-09-26 and reported
every one passing, then gave the go-ahead to merge.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 73d9b8b8670f0cc754ca91e7b126e444662a2eb8
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 15:33:02 2026 +0530
Docs: record the owner's in-client results for the settings layout
The owner ran this build's checks in the client on 2026-09-26 and reported
every one passing, then gave the go-ahead to merge.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 3a7ac1974d7563782733326d56160187f9190d03
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 15:15:09 2026 +0530
pm-band-fix-01: Show the Panels band's block and lay its row out at the band's width
THE PANEL PICKER AND THE CREATE NEW PANEL BOX COULD VANISH, leaving the band's
height and divider above the tab strip with nothing in them. drawPageHeader
builds the band's block with AceGUI:Create("SimpleGroup"), parents it by hand to
the header frame and anchors it, but never showed it. Real AceGUI pools widgets:
Release hides the frame and a later Create hands it back hidden, and only a
parent container's layout shows a child. The block is no container's child, so
once any addon had released a SimpleGroup earlier in the session, the band came
back hidden. First bad commit 081ee2c, which created the band; 1b8c672 fixed a
zero-width layout race that was never the mechanism, because the List layout
reads content.width, which a SimpleGroup starts at 300.
That 300 is the second defect. Anchoring the block to both sides of the header
stretches the frame and leaves content.width alone, so every DoLayout, the
OnSizeChanged re-layout included, laid the row out at 300 pixels and each
half-width control at 150. The hook now calls block:SetWidth(width) before
DoLayout, and the build does the same when the header already has a width.
Two cases in tests/test_panel.lua: the band is handed a hidden SimpleGroup, as
the pool hands it one, and its block, picker and create box must be shown; and a
size change must reach the layout as the block's width. Both red before the fix.
The comments in settings/PanelEditor.lua and the older test that described the
zero-width mechanism are corrected. docs/settings-panel.md explains both
defects, docs/smoke-tests.md 5-w checks the half-band widths and the new 5-x
opens another addon's settings first, docs/test-cases.md is regenerated, and
the README badge reads 964.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 3a7ac1974d7563782733326d56160187f9190d03
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 15:15:09 2026 +0530
pm-band-fix-01: Show the Panels band's block and lay its row out at the band's width
THE PANEL PICKER AND THE CREATE NEW PANEL BOX COULD VANISH, leaving the band's
height and divider above the tab strip with nothing in them. drawPageHeader
builds the band's block with AceGUI:Create("SimpleGroup"), parents it by hand to
the header frame and anchors it, but never showed it. Real AceGUI pools widgets:
Release hides the frame and a later Create hands it back hidden, and only a
parent container's layout shows a child. The block is no container's child, so
once any addon had released a SimpleGroup earlier in the session, the band came
back hidden. First bad commit 081ee2c, which created the band; 1b8c672 fixed a
zero-width layout race that was never the mechanism, because the List layout
reads content.width, which a SimpleGroup starts at 300.
That 300 is the second defect. Anchoring the block to both sides of the header
stretches the frame and leaves content.width alone, so every DoLayout, the
OnSizeChanged re-layout included, laid the row out at 300 pixels and each
half-width control at 150. The hook now calls block:SetWidth(width) before
DoLayout, and the build does the same when the header already has a width.
Two cases in tests/test_panel.lua: the band is handed a hidden SimpleGroup, as
the pool hands it one, and its block, picker and create box must be shown; and a
size change must reach the layout as the block's width. Both red before the fix.
The comments in settings/PanelEditor.lua and the older test that described the
zero-width mechanism are corrected. docs/settings-panel.md explains both
defects, docs/smoke-tests.md 5-w checks the half-band widths and the new 5-x
opens another addon's settings first, docs/test-cases.md is regenerated, and
the README badge reads 964.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 9357c0743ea95705c6332bb1130d6edf276ce3fc
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 14:44:11 2026 +0530
NR-PM-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. CLAUDE.md provenance rolls with it. The stub's table literal gains a NavRail no-op for the Options surface-parity case. The vendor diff gate is clean against ../LibKa0s.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 90c93353a111f53ae71fad50efff4719383a956d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 09:15:26 2026 +0530
DR-PM-07: Standards refresh to v2.68.0, docs synced, AUD-01 self-check passes
revendor-standards against WowAddonStandards v2.68.0 (2026-09-26, master
2854053, identical to origin/master): nothing to change.
- The three-place reference is intact: PanelMaster.toc:12 X-Standard, the
bare README badge (no link wrapper, no %20), and CLAUDE.md's Standards
compliance section with the stop-and-flag directive and the two-way
classification. None carries a version stamp.
- 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 -> 4 hits, all in
the frozen docs/revendor/2026-09-23-v1.55.0/ bundle, where they quote
the library's compat.md. Left as evidence.
- Every filename-§N reference range-checked against the section files'
own ### N. headings: none out of range, malformed or naming an unknown
file.
- No retired doc-set counts or labels outside frozen bundles. The standard
has no quirks-catalogue section, so there is no vendored block.
testing.md and automated-tests/README.md already name both checkpoints
(the RESULTS.md lead-in is runner-generated and not swept).
.gitattributes pins CRLF with the *.sh carve-out and binary markings;
0 worktree stragglers by the line-endings-§7 check.
sync-docs: one AUD-01 gap and one drift, both closed here.
- AUD-01 step 3 reads "tests/test_disabled.lua dispatches both forms".
Here Disabled 7 dispatched `/pm diagnostics` only, and the debug form
was covered by the kit's shared contract case alone. test_disabled.lua
gains "Disabled 7c: both diagnostics forms reach RunDiagnostics, each
once, with no refusal". It is a characterization case, since the route
already worked. Falsified twice, each time restoring the file: the
COMMANDS row's RunDiagnostics call removed (7c red, plus five others),
and the debug handler's DebugVerb call bypassed (7c red).
docs/testing.md describes 7c under the test_disabled.lua section.
- docs/ARCHITECTURE.md's localization-§1 deviation row said the one
NS.L string is printed by Sl:LibraryAbsentLine; the degraded DebugLog
stub's RunDiagnostics (core/DebugLogSetup.lua) prints it too now.
- docs/test-cases.md regenerated (961 -> 962); README badge 962/962. The
README change is the badge number only, so the de-AI pass had no prose
to review.
- Checked and unchanged: 20 verbs in NS.COMMANDS and the thirteen
reserved verbs (ARCHITECTURE, slash-dispatch.md), the Documentation map
both ways, module-map against the TOC load list and every suite, the
v1.60.0 provenance line, DEPENDENCIES.md, the path citations the
rollout's comments added.
AUD-01 (AUDIT.md diagnostics check), run by hand on this commit:
1. grep '"diagnostics"' settings/*.lua core/*.lua: one COMMANDS row
(Slash.lua:405); the other hits are the degraded fallback live list
(Slash.lua:455) and the stub's DebugVerb (DebugLogSetup.lua:87). The
debug handler (Slash.lua:400) hands the word to DebugVerb, which tests
`diagnostics` before on/off. PASS
2. grep -rniE '"(diag|dump|dx)"' settings core modules: one hit,
modules/Diagnostics.lua:25 `local TAG = "Diag"`, the report's line tag,
not a verb, debug word or alias. PASS
3. No liveVerbs passed (Slash.lua:441), so the live set is Slash 16's
LIVE_VERBS; the degraded fallback list carries diagnostics;
test_disabled.lua now dispatches both forms while disabled. PASS
4. Both forms call NS.DebugLog:RunDiagnostics (Slash.lua:406 directly,
Slash.lua:400 through DebugVerb); no :Clear in modules/Diagnostics.lua.
PASS
5. The stub's RunDiagnostics prints the library-absent line
(core/DebugLogSetup.lua:74-77). PASS
6. README ## Reporting a bug sits between Troubleshooting and Issues and
feature requests and matches documentation-§1 item 9 verbatim for /pm.
PASS
Result: AUD-01 passes (vendor v1.60.0, so no #47/#90).
Gate: lua tests/run.lua 962 passed, 0 failed; luacheck 0 warnings / 0
errors in 64 files; lizard -C 15 -w clean (libs and tests/_kit
excluded); largest Lua file 1447 lines. Every edited file keeps CRLF.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 90c93353a111f53ae71fad50efff4719383a956d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 09:15:26 2026 +0530
DR-PM-07: Standards refresh to v2.68.0, docs synced, AUD-01 self-check passes
revendor-standards against WowAddonStandards v2.68.0 (2026-09-26, master
2854053, identical to origin/master): nothing to change.
- The three-place reference is intact: PanelMaster.toc:12 X-Standard, the
bare README badge (no link wrapper, no %20), and CLAUDE.md's Standards
compliance section with the stop-and-flag directive and the two-way
classification. None carries a version stamp.
- 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 -> 4 hits, all in
the frozen docs/revendor/2026-09-23-v1.55.0/ bundle, where they quote
the library's compat.md. Left as evidence.
- Every filename-§N reference range-checked against the section files'
own ### N. headings: none out of range, malformed or naming an unknown
file.
- No retired doc-set counts or labels outside frozen bundles. The standard
has no quirks-catalogue section, so there is no vendored block.
testing.md and automated-tests/README.md already name both checkpoints
(the RESULTS.md lead-in is runner-generated and not swept).
.gitattributes pins CRLF with the *.sh carve-out and binary markings;
0 worktree stragglers by the line-endings-§7 check.
sync-docs: one AUD-01 gap and one drift, both closed here.
- AUD-01 step 3 reads "tests/test_disabled.lua dispatches both forms".
Here Disabled 7 dispatched `/pm diagnostics` only, and the debug form
was covered by the kit's shared contract case alone. test_disabled.lua
gains "Disabled 7c: both diagnostics forms reach RunDiagnostics, each
once, with no refusal". It is a characterization case, since the route
already worked. Falsified twice, each time restoring the file: the
COMMANDS row's RunDiagnostics call removed (7c red, plus five others),
and the debug handler's DebugVerb call bypassed (7c red).
docs/testing.md describes 7c under the test_disabled.lua section.
- docs/ARCHITECTURE.md's localization-§1 deviation row said the one
NS.L string is printed by Sl:LibraryAbsentLine; the degraded DebugLog
stub's RunDiagnostics (core/DebugLogSetup.lua) prints it too now.
- docs/test-cases.md regenerated (961 -> 962); README badge 962/962. The
README change is the badge number only, so the de-AI pass had no prose
to review.
- Checked and unchanged: 20 verbs in NS.COMMANDS and the thirteen
reserved verbs (ARCHITECTURE, slash-dispatch.md), the Documentation map
both ways, module-map against the TOC load list and every suite, the
v1.60.0 provenance line, DEPENDENCIES.md, the path citations the
rollout's comments added.
AUD-01 (AUDIT.md diagnostics check), run by hand on this commit:
1. grep '"diagnostics"' settings/*.lua core/*.lua: one COMMANDS row
(Slash.lua:405); the other hits are the degraded fallback live list
(Slash.lua:455) and the stub's DebugVerb (DebugLogSetup.lua:87). The
debug handler (Slash.lua:400) hands the word to DebugVerb, which tests
`diagnostics` before on/off. PASS
2. grep -rniE '"(diag|dump|dx)"' settings core modules: one hit,
modules/Diagnostics.lua:25 `local TAG = "Diag"`, the report's line tag,
not a verb, debug word or alias. PASS
3. No liveVerbs passed (Slash.lua:441), so the live set is Slash 16's
LIVE_VERBS; the degraded fallback list carries diagnostics;
test_disabled.lua now dispatches both forms while disabled. PASS
4. Both forms call NS.DebugLog:RunDiagnostics (Slash.lua:406 directly,
Slash.lua:400 through DebugVerb); no :Clear in modules/Diagnostics.lua.
PASS
5. The stub's RunDiagnostics prints the library-absent line
(core/DebugLogSetup.lua:74-77). PASS
6. README ## Reporting a bug sits between Troubleshooting and Issues and
feature requests and matches documentation-§1 item 9 verbatim for /pm.
PASS
Result: AUD-01 passes (vendor v1.60.0, so no #47/#90).
Gate: lua tests/run.lua 962 passed, 0 failed; luacheck 0 warnings / 0
errors in 64 files; lizard -C 15 -w clean (libs and tests/_kit
excluded); largest Lua file 1447 lines. Every edited file keeps CRLF.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit f9d00dfcd6c0203aeb300a81932297f9f7ca10d3
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 09:05:25 2026 +0530
DR-PM-05: Document /pm diagnostics in debug.md, smoke tests and the doc set
debug-logging-14 "Documented" (standard v2.68.0, STD-20): docs/debug.md
now documents the report that replaced /pm debug dump.
- debug.md: a `/pm diagnostics` section with both forms (and no alias;
`debug dump` and `debug diag` toggle the console), append and ungated
semantics, the one chat line, the shape (library frame, then the ten
sections of modules/Diagnostics.lua in order, all tagged [Diag]), the
per-panel lines, how to read it for a rendering bug, the stood-down
behavior, the caps (min(1200, 3000 - 100) = 1200 lines, 40 ids per
list, 200-char wrap), what it never does (no setter, Recover,
FitToArtwork, SetPoint, Show or queue replay; secret-safe; pcall per
section and per panel), the library-absent line, and nothing redacted
(owner ruling Q11). The rejected-events paragraph now describes the
`events` section. The buffer is named as lib.MAX_BUFFER, 3000.
- smoke-tests.md: the :685/:718/:881 counter lines read 3000 (DR-OW-02);
section 11 step 9 runs the report instead of the dump, and new steps
12-17 cover S2/S4 (trace kept, Copy clean), S5 (ungated, flag
untouched), S1 (disabled, both forms), S3 (combat, queue not flushed),
S8 (no alias) and S7 (the cap). The 11b and 12b-2 dump steps read the
report's frames line; section 14 step 10 expects the library-absent
line from both forms.
- common-tasks.md: "Debug a rendering problem" points at the report's
panels and frames lines; new "Add a section to the diagnostics report".
- ARCHITECTURE.md :189: the rejected list is the report's events section.
- module-map.md: State and DebugLogSetup rows no longer name the dump or
D:Diagnose; Unlock row names PendingSnapshot; new rows for
modules/Diagnostics.lua and tests/test_diagnostics.lua.
- core/DebugLogSetup.lua:9: the comment no longer states the line cap.
Documentation and one comment only; tests unchanged (test-cases.md and
the badge stand at 961). Every edited file keeps CRLF.
Gate (ka0s-bounded): lua tests/run.lua 961 passed, 0 failed, 0 skipped,
961 total; luacheck 0 warnings / 0 errors in 64 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 53fc258aef8cb10c29312c37b1c6280f0728cab7
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 08:59:54 2026 +0530
DR-PM-04: README gains ## Reporting a bug; Troubleshooting and Issues 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 `/pm` 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: the Troubleshooting row "Something is genuinely broken", which told
players to copy the debug log and attach it to an issue, now reads
"Something looks wrong and I want to report it -> Follow Reporting a bug
below." The Issues paragraph's "A debug log (see above) helps" line now
points at the section too.
The Usage paragraph on the disabled state lists `diagnostics` among the
verbs that still answer while the addon is off, which DR-PM-01 made true.
Verification (plan section 4): the section diffs clean against STD-17 apart
from the slash; no GitHub link in it. De-AI pass run on the new text; one
wording change to the Issues pointer. README keeps CRLF (303 CR / 303 LF).
Documentation only; tests unchanged.
Gate: lua tests/run.lua 961 passed, 0 failed; luacheck 0 warnings / 0
errors in 64 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 c3af1945eb9fd58713aa9319d03e51308fec1d16
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 08:57:48 2026 +0530
DR-PM-03R: Retire the last comments that still name the debug dump
The independent review of DR-PM-03 (497cad1) found the report, the
dispatcher and the tests sound, and found five comments that still named
the retired dump:
- modules/Registry.lua (two, in destroy and DeleteAll) and
tests/test_registry.lua: a stale unlocked id would show up "in a debug
dump". It now shows up in the `/pm diagnostics` report's "unlocked
panels" list, so the comments name the report.
- modules/Canvas.lua releaseArt and tests/test_canvas.lua: "a debug dump"
was listed among the things that show a pooled frame. Neither the old
dump nor the read-only report shows a panel frame, so it is dropped.
- tests/test_canvas.lua: "the kind of thing a `/pm debug dump` is read to
rule out" now names `/pm diagnostics`.
Comment-only; CRLF kept in all four files.
Gate (ka0s-bounded): lua tests/run.lua 961 passed, 0 failed, 0 skipped,
961 total; luacheck 0 warnings / 0 errors in 64 files; lizard -C 15 -w
clean; no 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 497cad19d6d26033ec07c4116f89c2397ab99977
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 08:53:46 2026 +0530
DR-PM-03: Diagnostics report on the LibKa0s helper; retire /pm debug dump
/pm diagnostics and /pm debug diagnostics now write the debug-logging-14
report (DX-PM) into the debug console, through LibKa0s DebugLog 14.1. The
library writes the markers, the identity header, the per-section pcall,
the cap and the ungated append; this addon supplies sections only.
- modules/Diagnostics.lua (new, in the TOC after Unlock.lua): ten sections
in order: state (schema stamp, profile, stored switch against the
latch, lifecycle holds, test mode), master (switches, global unlock,
individually unlocked ids), unlock queue (through
Unlock:PendingSnapshot, never flushed), settings (the Schema walk via
out:nonDefaults with settings.enabled always printed, plus
state.locked), screen, panels (per panel under its own out:section:
id, name, enabled, frame name, fields differing from PANEL_TEMPLATE,
renderer vs record size, live alpha vs target and mouseover floor, live
vs record anchor with recover's off-screen test, media resolution and
fallback per field, artwork resolution with custom paths verbatim;
"renderer: stood down" while stood down), frames (active, pooled,
orphaned), mouseover ticker, artwork catalog and Sunn packs, rejected
events. Read-only: no setter, no Recover, FitToArtwork, SetPoint or
Show, no queue replay; frame numbers are compared only when
out:readable says so.
- modules/Registry.lua: recover's clamp is lifted into the pure
R.RecoveredOffsets, and R.IsOffScreen asks the same question without
moving anything. R:Recover calls it; behavior unchanged.
- core/DebugLogSetup.lua: the descriptor passes brandName (NS.BRAND) and
diagnostics; D:Diagnose and its writers are removed from both arms.
- settings/Slash.lua: `debug` routes through DebugVerb (diagnostics
first, any case; on/off; anything else toggles the window), and a new
`diagnostics` row (20 verbs). `dump` is an ordinary unknown word now.
Tests (STD-19): tests/run.lua sets Kit.diagnostics, so the kit's
test_diagnostics_contract runs against the real dispatcher (both forms,
both while disabled, append, ungated, markers, retired `dump`); new
tests/test_diagnostics.lua holds 22 domain cases (sections and order,
stood-down run, queue left intact, off-screen flag without moving,
media and artwork resolution, a raising section and a raising panel
each costing one line, the over-cap truncated line, a secret mock, a
read-only watch over every writer, `debug dump` toggling the window).
The retired Diagnose cases in test_debuglog, test_disabled,
test_libka0s and test_slash are rewritten onto the report.
Docs: ARCHITECTURE.md verb counts (19 -> 20, diagnostics no longer a
reservation) and the debug.md trigger row; slash-dispatch.md verb lists;
code comments that named /pm debug dump. debug.md, common-tasks,
module-map and smoke-tests are DR-PM-05. test-cases.md regenerated
(961 cases), README badge 961/961.
Verification: grep -rniE '"(diag|dump|dx)"' settings core modules
matches only modules/Diagnostics.lua's line tag `"Diag"`, which is not a
verb or word; no report alias exists.
Gate (ka0s-bounded): lua tests/run.lua 961 passed, 0 failed, 0 skipped,
961 total; luacheck 0 warnings / 0 errors in 64 files; lizard -C 15 -w
clean; no 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 7d381ac244617063a715ad15ba5308de2bf47def
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 04:12:27 2026 +0530
DR-PM-02: Add a read-only snapshot of the combat unlock queue
The diagnostics report (DX-PM, DR-PM-03) prints the combat unlock
queue, but pendingUnlock and pendingPanels are file-locals in
modules/Unlock.lua and the only way in was the __hasPending test seam.
Unlock:PendingSnapshot() returns a fresh table every call: `unlock` is
the global request and `panels` the queued per-panel ids in ascending
order. It is a copy, so no reader can flush or edit the queue, and
reading it never replays anything.
New case in test_unlock.lua: the snapshot reports the queue, is sorted,
does not alias the live state, and reading it neither flushes the queue
nor applies the unlock. docs/test-cases.md regenerated (936 cases) and
the README badge moves to 935/935.
Gate: lua tests/run.lua 935 passed, 0 failed, 1 skipped (the
diagnostics contract, wired in DR-PM-03); 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 8a7af84241be69c31152abb6da5594785b11069f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 03:56:22 2026 +0530
Docs: Count diagnostics among the thirteen reserved live verbs
LibKa0s v1.60.0 (Slash minor 16) added `diagnostics` to lib.LIVE_VERBS,
so the standard's reserved set is thirteen verbs, not twelve. ARCHITECTURE.md
and slash-dispatch.md still named twelve at Slash minor 13. ARCHITECTURE.md
now lists `diagnostics` beside `perf` as a reservation this addon does not
register, so the eleven shipped reserved verbs are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 8a7af84241be69c31152abb6da5594785b11069f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 03:56:22 2026 +0530
Docs: Count diagnostics among the thirteen reserved live verbs
LibKa0s v1.60.0 (Slash minor 16) added `diagnostics` to lib.LIVE_VERBS,
so the standard's reserved set is thirteen verbs, not twelve. ARCHITECTURE.md
and slash-dispatch.md still named twelve at Slash minor 13. ARCHITECTURE.md
now lists `diagnostics` beside `perf` as a reservation this addon does not
register, so the eleven shipped reserved verbs are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 0371307bb691ce6434e2e9d10364326e4b62e65a
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 03:52:15 2026 +0530
DR-PM-01: Re-vendor LibKa0s v1.60.0; stub RunDiagnostics, diagnostics joins the live list
Re-vendor both payloads whole from tag v1.60.0 (commit bed0eb1), carrying
v1.59.0 in the same copy: DebugLog 13 -> 14, the new DebugLogDiagnostics.lua
minor 1, Slash 15 -> 16, WidgetsDragHandle 2 -> 3, kit revision 26 -> 27. The
CLAUDE.md provenance line moves to v1.60.0 in this commit.
What the copy made owed, in the same commit so the suite stays green:
- core/DebugLogSetup.lua: the library-absent DebugLog stub gains
RunDiagnostics (the collection's library-absent line naming
/pm diagnostics, nothing written, returns 0), BuildDiagnostics and
DebugVerb, so the surface-parity case matches DebugLog 14.1.
- settings/Slash.lua: the degraded LIVE_VERBS fallback gains diagnostics.
- tests/test_slash.lua: the live-set pin gains diagnostics.
- tests/run.lua: declares the kit's test_diagnostics_contract suite, which
skips with its reason until DR-PM-03 sets Kit.diagnostics.
- tests/test_libka0s.lua: one case for the stub's three members.
No host test pins the 1500-line buffer. The report itself, the unlock
queue accessor and the retirement of /pm debug dump are DR-PM-02 and
DR-PM-03. No decline issues filed; the rollout plan decided every surface.
The revendor bundle is docs/revendor/2026-09-26-v1.60.0/. test-cases.md is
regenerated and the README badge reads 934/934.
Gate (ka0s-bounded): lua tests/run.lua 934 passed, 0 failed, 1 skipped,
935 total; luacheck 0 warnings / 0 errors in 62 files; lizard, no function
above CCN 15.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit c078d7e4c995b842566c1b48ece7fe447d273adc
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Sep 25 00:13:12 2026 +0530
M6-PM: address review — drop stale "LibDBIcon right-click menu" comments
What: reword the comments in tests/test_launcher.lua (header, the
Minimap-row path test, the table-identity test), settings/Schema.lua
(S.MINIMAP_STORE note, the inversion note) and defaults/Global.lua
that still said LibDBIcon's own right-click menu writes `hide`.
Why: after 494c479 right-click opens the Ka0s options menu, which never
writes `hide`, and LibDBIcon ships no such menu. The writers of `hide`
are the Minimap button row (NS.Launcher:SetShown) and
/pm set global.minimap.shown; LibDBIcon only reads it and writes
minimapPos on drag. The comments now match docs/schema.md as reworded
in 494c479.
Departures: comments only, so there is no test to write first. Also
reworded a seventh comment in the same identity test ("as its menu
does") carrying the same claim.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit c078d7e4c995b842566c1b48ece7fe447d273adc
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Sep 25 00:13:12 2026 +0530
M6-PM: address review — drop stale "LibDBIcon right-click menu" comments
What: reword the comments in tests/test_launcher.lua (header, the
Minimap-row path test, the table-identity test), settings/Schema.lua
(S.MINIMAP_STORE note, the inversion note) and defaults/Global.lua
that still said LibDBIcon's own right-click menu writes `hide`.
Why: after 494c479 right-click opens the Ka0s options menu, which never
writes `hide`, and LibDBIcon ships no such menu. The writers of `hide`
are the Minimap button row (NS.Launcher:SetShown) and
/pm set global.minimap.shown; LibDBIcon only reads it and writes
minimapPos on drag. The comments now match docs/schema.md as reworded
in 494c479.
Departures: comments only, so there is no test to write first. Also
reworded a seventh comment in the same identity test ("as its menu
does") carrying the same claim.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 494c47959a71e9a33d01d2922fd1318231142753
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Sep 25 00:08:43 2026 +0530
M6-PM: Re-vendor LibKa0s v1.58.0; launcher menu is Enabled and Locked
What: replace libs/LibKa0s/ and tests/_kit/ whole from the local tag
v1.58.0 (tag 93cf3ad -> commit 34931c9), extracted with git archive
(never a checkout in ../LibKa0s), and roll the CLAUDE.md provenance
line v1.57.0 -> v1.58.0. One minor moves, Launcher 3 -> 4; the kit
stays at revision 26, byte-identical. Frozen bundle
docs/revendor/2026-09-25-v1.58.0/ (01_DELTA.md, 05_SUMMARY.md), shaped
like M5-PM's v1.57.0 bundle.
Adoption (launcher-section 2, WowAddonStandards v2.67.0): left-click
opens settings (the library's), right-click opens the options menu.
core/LauncherSetup.lua passes the two pairs this addon really has:
- isEnabled + setEnabled -> NS.Slash:CliEnable, the body of
/pm enable and /pm disable;
- isLocked + toggleLock -> NS.Slash:CliLock(not isLocked()), the body
of /pm lock and /pm unlock (CliSet on state.locked: the single write
seam, one [Set] trace, the path = value echo, the combat deferral).
No test mode (unlocking is the preview) and no primary window, so no
toggleTestMode and no isWindowShown/toggleWindow. The menu matches the
row WowAddonStandards' ADDONS.md records (WS-11): "Enabled . Locked".
Removed onClick (rung b), leftClickLabel (and its two NS.L keys in
locales/enUS.lua, with the PostLoad.lua note restored) and the retired
disabledLine. Kept version, isLocked, isEnabled.
Tests (written against the copy; red against the old LauncherSetup):
tests/mock_menu.lua is LibKa0s v1.58.0's own repo-local MenuUtil mock,
copied with a provenance header (the kit ships none). test_launcher.lua
re-pins the clicks and hints and adds the menu: exact entries and order,
state read per open, each entry routing to its slash handler both ways,
the write seam and combat deferral, grayed Locked while disabled writing
nothing, and the no-MenuUtil fallback. test_disabled.lua case 8 now
proves the disabled left click opens the panel and writes nothing.
Docs: README (minimap paragraph, disabled paragraph, badge 933/933),
ARCHITECTURE.md (launcher table, disabled-survivor row, localization
row), settings-panel.md (Minimap button row), module-map.md (seam row,
test_launcher row, mock_menu.lua row), smoke-tests.md 7b steps 3-4c,
slash-dispatch.md, schema.md, testing.md tree, test-cases.md
regenerated (test_launcher 32 -> 37, total 933).
Departures:
- One commit rather than copy-then-adopt: the copy alone reddens ten
cases pinning the retired rung (b) click, refusal and hints.
- The lint config gains a narrow files["tests/mock_menu.lua"] stanza
(212/self, 432/self) so the copied mock stays byte-identical below
its header.
- smoke-tests.md steps 8/8b and schema.md described hiding the button
through "LibDBIcon's own right-click menu"; right-click is now the
options menu, so those lines point at the Minimap button row instead.
Gates (all through ka0s-bounded): tests 933/933; lint 0/0 in 62 files;
complexity nothing 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_01HTuhyvd3dgxDekBFUvKcoZ
commit efbd2d90e3f3375eed0aed70b864af99791dae13
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 23:13:43 2026 +0530
M5-PM: Launcher tooltip fields: version, isEnabled, isLocked, left label
What: core/LauncherSetup.lua passes the Launcher minor 3 descriptor
fields launcher-section 1 (WowAddonStandards v2.66.0) owes, each read
on every show by the library-drawn status tooltip:
- version -> NS.Version(), the TOC's ## Version (the /pm version seam);
- isEnabled -> NS.IsAddonEnabled (the master switch, not the Lifecycle
latch), with disabledLine -> the Slash dispatcher's DisabledLine(), so
the tooltip reads Enabled: Yes|No and, while disabled,
"Left-click: disabled -- /pm enable";
- isLocked -> state.locked, the accessor the Lock frame row reads;
- leftClickLabel -> "Unlock frame" / "Lock frame" by lock state (rung
(b), "lock / unlock" in ADDONS.md), through NS.L (two keys added to
locales/enUS.lua).
No isTestMode (this addon has no test mode; unlocking is its preview)
and no onTooltipShow (it never passed one and has no line of its own).
Tests (written first, red on the vendored library alone): seven cases in
tests/test_launcher.lua that hover the object's OnTooltipShow into a
recording tooltip and pin the whole block enabled and disabled, the TOC
version, re-reading on every show, the green/red values, the absent
Test mode line, and the library's gate refusing a disabled left click
exactly once.
Docs: ARCHITECTURE.md launcher table gains the tooltip row, the
disabled-state row and the localization-section-1 row are updated;
settings-panel.md Minimap button row, module-map.md, README (the
minimap paragraph, the disabled paragraph, the Tests badge 928/928),
smoke-tests.md step 7b.4c, and docs/test-cases.md regenerated
(test_launcher 25 -> 32, total 928).
Departures:
- Passing isEnabled (needed for a true Enabled: line) makes the
library's minor-2 gate refuse the disabled left click, so the host's
own copy of that gate inside toggleLock is removed: one refusal, same
line, same single chat line (tests/test_disabled.lua case 8 unchanged
and green).
- The first M5-PM commit (f993d63) wrote the revendor bundle's two .md
files with doubled CRs (CR CR LF), which the kit's eol gate reads as
lone CRs; its "921/921" was measured before the bundle was added. This
commit restores CRLF in both files; no content change.
Gates (ka0s-bounded): tests 928/928; luacheck 0/0 in 61 files; lizard
nothing 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_01HTuhyvd3dgxDekBFUvKcoZ
commit f993d632b2b6afdd484c491c84babf373694cb13
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 23:12:38 2026 +0530
M5-PM: Re-vendor LibKa0s v1.57.0 and record its delta bundle
What: replace libs/LibKa0s/ and tests/_kit/ whole from the local tag
v1.57.0 (tag d03e836 -> commit aa37bc9), extracted with git archive
(never a checkout in ../LibKa0s), and roll the CLAUDE.md provenance
line v1.56.0 -> v1.57.0 in the same commit. One library file moves a
minor: Launcher 2 -> 3. The kit stays at revision 26, byte-identical.
Both payloads diff empty against the tag, with and without
--strip-trailing-cr.
Adds the frozen bundle docs/revendor/2026-09-24-v1.57.0/ (01_DELTA.md,
05_SUMMARY.md), shaped like the RV-PM bundle for v1.56.0: base,
per-file minors, both diffs, kit pairing, consumption map, contract
delta. No contract blocker: this host never passed onTooltipShow.
Why: M5 (the owner's 2026-09-24 smoke ruling, WowAddonStandards
v2.66.0 launcher-section 1): the library now always draws the minimap
button's status tooltip. The descriptor fields this addon owes are the
second M5-PM commit.
Gates after the copy (all through ka0s-bounded): tests 921/921; lint
0/0 in 61 files; complexity nothing 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_01HTuhyvd3dgxDekBFUvKcoZ
commit a3b4390f2f6879fcad4ad3cfe514548926a893e2
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 13:26:48 2026 +0530
PM-16: Refresh the standards reference against v2.65.0
Ran the /wow-addon:revendor-standards procedure against the standard as
published on WowAddonStandards master (v2.65.0, 2026-09-23). The
execution gate held: gh api .../contents/standards/STANDARDS.md reads
v2.65.0 on the default branch.
Three-place reference (documentation-§6): TOC ## X-Standard carries the
repo URL, the README badge is the bare image with no link wrapper and no
%20 escapes, and CLAUDE.md "Standards compliance (read first)" matches
the canonical block verbatim, stop-and-flag and the two-way
classification intact. Nothing to change.
Sweep (whole repo, excluding libs/, tests/_kit/ and the frozen docs/
audits, reviews, automated-tests, revendor, superpowers, investigations):
grep -rEn '§[0-9]+\.[0-9]' . <those exclude-dirs> -> 0 hits
Every filename-§N citation range-checked against the fetched section
files' '^### N.' counts: none unknown or out of range. The one
malformed one was tests/prose_waivers.lua:3 'localization-5'.
No doc-set counts without members, no drop-in wording. 3f gate
statements in docs/testing.md, docs/automated-tests/README.md and
CLAUDE.md already name both checkpoints (commit, tag). The standard has
no quirks catalogue section, so nothing is vendored. .gitattributes is
the canonical CRLF body with the *.sh carve-out and binary marks;
worktree stragglers: 0. No renormalization done.
Changes (comment-only):
- tests/prose_waivers.lua:3: 'localization-5' -> 'localization-§5'.
- settings/Slash.lua:279: the library-absent line comment now cites
slash-commands-§1 at standard v2.65.0, as PM-09 relied on it. Kept to
one line so no file:line citation elsewhere shifts.
The savedvariables-§1 schemaVersion = 0 citation (defaults/Global.lua:9,
tests/test_database.lua:92) and the launcher-§3 minimap.shown citation
(tests/test_launcher.lua:220/303, docs/smoke-tests.md:475) already
carried v2.65.0 from PM-10/PM-11; verified, not touched.
Deviation: the item's verify expects 'v2.65.0' in README.md and
CLAUDE.md. Neither file carries a standard version, and the procedure
forbids writing one into the reference (a version on a pointer goes
stale silently; documentation-§6 prescribes no version). Left as is.
'v2.64.0' appears nowhere in README.md, CLAUDE.md, PanelMaster.toc or
docs/*.md.
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 689a7919e1a81d4db7aad86d642ad4fd7b51706d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:50:14 2026 +0530
PM-DOCS: Sync docs and record the remediation's automated-test bundle
Closes the 2026-09-23 remediation's PanelMaster docs item (finding
PanelMaster-A-18). No version bump, no tag, no TOC change.
sync-docs pass:
- CLAUDE.md already matched (provenance line v1.56.0 as RV-PM rolled it,
ten of fifteen majors adopted; kit revision 26 is vendored, and no live
doc claims a current kit revision). Its Canvas citation was stale.
- Stale file:line citations re-derived against HEAD: the mouseover tick
Canvas.lua:650-656 -> 647-652 and its install :660/:666 -> :662
(CLAUDE.md, ARCHITECTURE.md, performance.md); mouseover default
Constants.lua:306 -> 311; NS.COMMANDS Slash.lua:285 -> 322;
PANEL_TEMPLATE :262 -> 267, PANEL_FIELD_ORDER :504 -> 509, preview
marker :548 -> 546; enUS.lua reasoning 8-14 -> 8-10; scheduleTimer seam
OptionsSetup.lua:234 -> 248; the 212/filter ignore :203 -> 217.
- performance.md's RegisterEvent table named core/PanelMaster.lua lines
that no longer register anything: the three stand-up events are
registered from core/LifecycleSetup.lua:73-75 (handlers at
core/PanelMaster.lua:112/124/137) and PLAYER_LOGIN from :67.
- settings-panel.md still said the General Defaults tooltip promised
"Your panels are untouched"; 900b085 fixed tooltip and comment, so the
paragraph now says what they read.
- ARCHITECTURE.md cap census recounted: PanelEditor.lua 1476 -> 1447,
test_panel.lua 1353 -> 1399, five files in the band, not four.
- Slash parity: 19 verbs in NS.COMMANDS, all named in ARCHITECTURE.md and
slash-dispatch.md. Dead-export sweep over core/modules/settings: none.
- docs/test-cases.md already equals `tests/run.lua --list` (921) and the
README Tests badge already reads 921/921; neither needed a change.
Bundle docs/automated-tests/20260924-104311/ (label
remediation-2026-09-23, not --release): lint pass 0/0 over 61 files,
tests 921/0/921, perf skip with reason (1) "no tests/perf.lua" (the
register row is performance-§1, so reason (2) is correctly not written),
complexity pass, 0 functions above CCN 15. Run on bf1291d with only the
doc edits above uncommitted; ANALYSIS.md says so. RESULTS.md rolled by
the runner; dispositions carried forward and updated for PanelEditor.lua,
test_panel.lua, test_artwork.lua and Artwork.lua. ANALYSIS.md records
once, forward-only, that 1.1.1-release (dd04000) was tagged with no
release bundle on a TOC reading 1.1.0 (automated-tests-§6). No bundle is
stamped 1.1.1.
Deviations:
- The item expected four band files; the run found five. The fifth,
tests/test_libka0s.lua (1086, up from 971 through PM-09 and PM-12),
arrived with a blank Disposition and has been given one (Accepted,
re-check at 1300, seam = its Degraded cases).
- Comment citation not corrected (the item allows that only on
confirmation): core/Database.lua:86 cites modules/Registry.lua:204-206
for the frame-name backfill, which now sits at :205-207.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit bf1291da8ba9f851c18dda427a7b472118cfdd1e
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:36:53 2026 +0530
PM-24: README Usage drops placeholders, ends on the config pointer
README.md Usage section, per documentation-§1:
- `/pm delete <name>` becomes `/pm delete ChatBG`, and `/pm get <setting>`
/ `/pm reset <setting>` become `/pm get settings.gridSize` /
`/pm reset settings.gridSize` (a real schema path), so CurseForge no
longer strips the argument. The only remaining angle-bracket markup is
the <br> in the Version History table.
- The two disabled-state paragraphs are merged into one, and the
`/pm disable` / `/pm enable` sentences move out of the settings-CLI
paragraph into it, so the disabled state is described in one place.
- The "Everything else is configuration..." pointer moves to be the last
paragraph of Usage (dropping the stale "now").
- A light de-AI pass over the edited paragraphs: em dashes out, "Those
settings" re-anchored now that the pointer no longer precedes it.
Finding: PanelMaster-A-14.
Deviation: the README never shows the minimap row's CLI path, so the
item's global.minimap.shown clause (PM-11) had nothing to rewrite.
Gates: luacheck 0/0, tests 921/921.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 2e1dc643928312aea1b3a8cf0a0ef4aa2d0be822
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:34:12 2026 +0530
PM-23: Cite the kit by function name as well as by re-derived line
DEPENDENCIES.md's toolchain rows cited tests/_kit by bare line number,
and two of those numbers predated the v1.56.0 payload (LK-01 peeled the
assertions out into tests/_kit/asserts.lua, shifting framework.lua).
- POSIX-shell row: `framework.lua:515-516` becomes `listDir` (:432, the
ls -A / dir /b shell-outs at :444-445); `framework.lua:498-500`
becomes the LuaFileSystem note on listDir (:427-431); the find
citation names `localNames` (:111, find at :126).
- Lua 5.1 row: loader.lua :68/:72 verified and named `Loader.load`.
- git row: vendor_sync.lua :195/:194 verified; names `gitOut` (:193).
Every line re-derived with sed -n against the vendored v1.56.0 kit.
docs/testing.md and CLAUDE.md carry no tests/_kit/<f>:<n> citations.
Resolves PanelMaster-A-13.
Deviation: docs/testing.md's harness tree still said framework.lua holds
"the assertions"; it now lists asserts.lua beside it, the same LK-01
drift the item names.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit c1a377741896bcf4098c2e2e10d1b133aaa639d4
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:32:43 2026 +0530
PM-22: address review — scope the atomic-write claim, name every degraded_env consumer
module-map's tools/ intro said all four generators write through .tmp and
os.replace; build_manifest.py and artwork_cleaner.py's TGAs write in place.
The degraded_env.lua row now names all five suites that load it
(test_disabled, test_launcher, test_libka0s, test_schema, test_surface_parity).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit d4b014cb0c335834bc89372c91028d61702f3a6a
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:28:55 2026 +0530
PM-22: Inventory tests/ and tools/ in module-map; recount stale claims
Resolves PanelMaster-A-11 and PanelMaster-A-12.
A-11: docs/module-map.md gains a "## tests/" section (run.lua,
wow_mock.lua, degraded_env.lua, prose_waivers.lua, and one row per
test_*.lua suite, all 28) and a "## tools/" section with the four
generators and what each writes. The basename check over tests/*.lua,
tools/artwork/*.py and tools/sunn/*.py now finds every file.
A-12, recounted by command:
- Adopted seams: ten (seven Setup files in core/, three in settings/).
ARCHITECTURE.md's Module Map said "six of the eight" and "the other
two"; it now says seven of the ten and the other three.
- Majors: fifteen NewLibrary calls in libs/LibKa0s, fourteen resolving
LibKa0s-Core-1.0. testing.md:106 and module-map's TOC-order note
("the other nine") now say fourteen of fifteen / the other fourteen.
- Parity cases: eight. testing.md's degradation-stub section already
said eight seams (PM-13), so it needed no change.
- ARCHITECTURE.md's doc table no longer calls RESULTS.md "never
hand-edited": its watch-list Disposition column is authored.
- testing.md's historical "six of the eight scripts" note is reworded
so it no longer reads as a current seam count.
settings/PanelEditor.lua: the tab-constants block no longer says
General is GONE (it is back and first), the strip-order note puts
General first, and the page-header block describes the one-row band
and the in-place picker refresh instead of three rows and the deleted
refreshHeaderActs. 1487 -> 1447 lines. The shifted line citations in
docs/compat-layer.md, docs/settings-panel.md and docs/smoke-tests.md
are rolled to match (settings-panel's :77/:1328 pair was already off
and now points at currentRecord's definition and call).
.gitignore: re-pointed from the nonexistent wiki_import.py to
tools/artwork/artwork_cleaner.py.
Deviations:
- The item says artwork_cleaner.py writes manifest.tsv.root and
.stamps.tsv. grep shows it writes only .stamps.tsv (it has no
manifest). The .root ignore line is kept, commented as the retired
importer's, so a stale copy on an old checkout cannot be committed.
- The item's grep for the stale phrases still hits the frozen
docs/audits/2026-09-23/ bundle (which quotes them as evidence) and
a frozen docs/superpowers spec (wiki_import.py). Frozen bundles are
not edited; every live doc and .gitignore is clean.
Gates: luacheck 0/0; tests 921 passed, 0 failed; complexity 0
functions above CCN 15; largest authored .lua is
settings/PanelEditor.lua at 1447 lines.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit edca9b9008b2c5d9c24c97d519c303a281024918
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:21:41 2026 +0530
PM-21: Restore ARCHITECTURE.md to the hub shape; spill runtime to schema
docs/ARCHITECTURE.md was 489 lines with a 106-line Settings Schema
section (documentation-§3 hub-and-spill rule). It is now 380 lines, and
the Settings Schema section is 42.
- Settings Schema keeps a five-line summary, the panel-registry block
(storage keys, writer, load pass) and one link out to schema.md. The
fields-on-a-panel narrative shrinks to a pointer at its register row.
- docs/schema.md gains '## The schema runtime': the 15 rows in 3 tabs,
the Master controls composition, the writeThrough enable path when the
composed row is missing (PM-09: Set/SetMany store settings.enabled raw,
Sl:CliEnable re-runs NS.RefreshEnabled), the global.minimap.shown row
and its inversion (PM-11), the library instance, and the degradation
stub (now citing docs/api/Schema/version-2-docs.md, as the code does).
- Retired-row narratives collapse to one entry each: options-ui-§16 x3
(#48, docs/revendor/2026-09-12-v1.31.0/), documentation-§4 (PM-029),
options-ui-§1 and line-endings-§5 (same M5-02 pass, docs/audits/
2026-09-08/), and the band gate (docs/revendor/2026-09-23-v1.55.0/).
- Headings renamed to the canonical '## Message Bus' and
'## Taint Notes'; the Documentation map's message-bus.md row follows.
No in-repo anchor pointed at either old heading, and tests/test_docs.lua
pins neither.
Finding: PanelMaster-A-10.
Deviations:
- The existing fields-on-a-panel paragraph in schema.md already carried
that narrative, so it was not duplicated; instead its stale trigger
("an explicit record argument on NS.Schema:Set") was brought into line
with the PM-15 register row (host-side resolveRoot + id forwarding,
#54), and its "ARCHITECTURE.md -> Settings Schema lists them" now
points at the register row, which does.
- The item's line cites (:47-78, :80-103, :380-428) predate PM-09..PM-20;
the moved blocks were located by content.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 3145831eb52162401ec659a8b1706052382090aa
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:17:25 2026 +0530
PM-20: address review — compat-layer test note names the five covered shims
docs/compat-layer.md said tests/test_compat.lua covers the degraded answers
of seven shims. Only five (GetUIScale, FetchMedia, MediaList, RegisterMedia,
InCombat) have degraded-path tests; GetScreenSize and MouseIsOver are tested
on their normal answers only. Reword the note to name the five and state the
two gaps plainly.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit b81f45076d897232626490ef089ecef2b7164a96
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:14:44 2026 +0530
PM-20: Write docs/compat-layer.md for the eight Compat shims
core/Compat.lua publishes eight shims (documentation-§3's mechanical
grep), over the trigger's threshold of three, yet the Tier 2 page was
missing and the map row said Not applicable. The new page has one
section per shim: what varies, what the guard answers when the API is
absent, and who calls it (grepped NS.Compat.<X>). InCombat is written
up in its PM-03 form (UnitAffectingCombat first, then InCombatLockdown,
then false). It links #53, the declined LibKa0s-Compat-1.0 adoption,
as the reason all eight stay addon-owned, and cites compat's v2.65.0
applicability condition (WS-05): this addon owns version-variant calls,
so Compat.lua is required. The ARCHITECTURE.md map row flips to
Present. tests/test_docs.lua does not pin the map, so no test changed.
Resolves: PanelMaster-A-04 (PanelMaster#53 referenced)
Deviations: the item's line cites were stale after PM-03 lengthened the
InCombat comment. Re-derived: InCombat :86, RegisterMedia :115,
FetchMedia :136, MediaList :151, MouseIsOver :176 (item said :79, :103,
:124, :139, :164). The map row is at docs/ARCHITECTURE.md:345, not :327.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 9b015fbd747df9d6e7842ca7025105a45a9a8ec7
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:10:30 2026 +0530
PM-19: Correct stale printer, AceConsole and PEW-rationale comments
Text only (PanelMaster-R-09, the sentences PM-09/PM-10 left):
- core/PanelMaster.lua reclaim comment: NS.Print is built by
core/CoreSetup.lua (the LibKa0s-Core printer), not defined in
core/Util.lua.
- core/CoreSetup.lua: the embed overwrites NS.Print with AceConsole's
:Print, not AceGUI's.
- core/PanelMaster.lua (OnEnterWorld), core/LifecycleSetup.lua
(NS.StandUp's gate note), docs/ARCHITECTURE.md and docs/data-flow.md
event tables: drop "the registry's off-screen recovery measures
UIParent" (recovery is on demand only, /pm recover). The real reason
for painting at PLAYER_ENTERING_WORLD is stated instead: panels are
anchored to UIParent (modules/Canvas.lua), whose final size and the
frame anchors are settled by that event and not at OnEnable. The
boot stand-up explanation is kept.
tests/test_docs.lua pins none of these strings. No line citations into
core/PanelMaster.lua needed rolling after its two added comment lines.
Deviations: the item's line cites had drifted (LifecycleSetup 120-122,
ARCHITECTURE.md:240, data-flow.md:204); the intended sentences were
edited at their current locations.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit d805e0b1a7801d8d4d099f0720f05c814a2e81ef
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:06:51 2026 +0530
PM-18: Record the 28 unrecorded LibKa0s tags in one span bundle
Add docs/revendor/2026-09-24-v1.16.0-v1.54.2/ (01_DELTA.md and
05_SUMMARY.md only), the consolidated span bundle audit-review-history
sanctions for a lapsed re-vendor record. Line 1 of 01_DELTA.md is the
WS-01/WA-01 grammar, `Delta: LibKa0s v1.16.0 -> v1.54.2 (span: ...)`,
naming every tag this addon vendored since the store's horizon
(2026-08-25) that no bundle names. The body states the true previous
base (v1.15.0, b7b744c), the two listing commands and their output, and
a tag / vendoring commit / date table; 05_SUMMARY.md carries one line
per tag (carried by sweep, nothing adopted, or the adopting commit's
sha) and why the record is consolidated. Frozen bundles are not edited.
With the folder in place, the AUDIT.md re-vendor check (and Step 3h's
walk with provenance rolls) prints nothing. Tests 921/0, luacheck 0/0,
no function above CCN 15.
Resolves: PanelMaster-A-15
Deviation: the item's list has 27 tags and omits v1.43.0, which
eaa7807 vendored (kit revision 23) and no bundle names. The re-derived
list the item asks for has 28, so the span names 28; without v1.43.0
the audit check would still print it. The item's own derivation
command (grep 'LibKa0s[^v]*v...' on CLAUDE.md) no longer matches the
provenance line's wording, so the listing uses AUDIT.md's
`Bundles [LibKa0s](...) vX.Y.Z` pattern instead. The span separator is
a space, per the audit-review-history grammar, not the comma-separated
form in the item text.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 7db8c12cdb7aea7e002e6ce23f2d8eafa84fd86c
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:01:43 2026 +0530
PM-17: Restore 'catalogued' in the two frozen superpowers specs
Line 5 of docs/superpowers/specs/2026-07-31-panel-artwork-design.md and
docs/superpowers/specs/2026-08-02-wiki-artwork-import-design.md is put back
byte-for-byte from e30e329^, undoing that commit's respelling of the frozen
text ("catalogued" had been mangled to "catalogd"). Both specs are frozen
records, not this repo's live English to correct.
The kit's prose gate no longer reads them: kit revision 26 (LibKa0s v1.56.0,
LK-07) adds docs/superpowers/ to SKIPPED_DIRS in tests/_kit/prose_lists.lua.
tests/prose_waivers.lua carried no interim skipDirs entry for that folder, so
nothing there needed removing. Prose gate green, 921 passed / 0 failed.
Finding: PanelMaster-A-09.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 62a16838ecc088ba1d6967a7e6017a6bdb9b8684
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:58:49 2026 +0530
PM-15: Re-decide the architecture-§5 trigger as host-side, cite #54
The architecture-§5 register row (the fields on a panel) had a re-check
trigger, "the schema helper gains instance addressing", that the library
already met: LibKa0s-Schema-1.0 has forwarded instanceId to resolveRoot
since minor 2. The host never used it, so the trigger was ambiguous and
un-evaluated (audit-review-history's third MUST).
Re-decided as keep (option b, the default decision):
- The trigger now names the host-side condition: settings/Schema.lua's
resolveRoot maps an instance id to a registry record AND
NS.Schema:Set/:Get forward that id.
- Decided is re-dated to 2026-09-24.
- Option (a), the adopt path, is filed as #54 (enhancement,
state:triaged, severity:low) and cited from the row.
Issue store (A-19), done through gh with 5 s between writes:
- #19, #20, #22, #23 relabelled state:done and closed with evidence.
- #24 relabelled state:will-not-do and closed as not planned, citing the
ratified performance-§1 row.
Findings: PanelMaster-A-07, PanelMaster-A-19.
Deviation: the item cites CLAUDE.md:83 for the agent-context.md
deletion; the sentence is at CLAUDE.md:84, and #19's close comment cites
:84.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 10f750cfff1a4dca9ca9f82a6ae283c577f1a09b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:55:01 2026 +0530
PM-14: Comment the TOC's load-bearing positions and conventional groups
PanelMaster.toc now says why two positions matter and which runs are
convention only (PanelMaster-A-02, PanelMaster-A-03):
- Util AFTER Constants is load-bearing: core/Util.lua:4 captures
`local C = NS.Constants` at file scope.
- Slash AFTER Schema is load-bearing: its dispatcher descriptor takes
NS.SchemaRuntime's members as values at file load
(settings/Slash.lua:601-605).
- Conventional notes on the Namespace/State run, the
PanelMaster/Database run, # Defaults, and # Modules (where Unlock is
the one conventional entry among the pinned ones).
Comments only. Loader.tocFiles skips '#' lines, so the TOC-derived load
list and tests/test_harness.lua's pin are unchanged (921 passed).
Deviations: the item cited Slash.lua:554-558; the lines are 601-605
today. Namespace/State and PanelMaster/Database got separate notes,
since CoreSetup sits between them with its own pin.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit e2a8ce98d01546d5ad2587a8be8a7c1ae83ccc32
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:52:30 2026 +0530
PM-13: Add the surface-parity case for the Lifecycle degradation stub
core/LifecycleSetup.lua's library-absent arm keeps the stand-down latch
itself, and its comment (and docs/module-map.md) claimed
tests/test_surface_parity.lua compared the two member sets. No case did.
Now one does (PanelMaster-A-08).
- tests/test_surface_parity.lua: new case "Parity: the Lifecycle seam's
degraded surface matches the live one". The degraded arm is a real
load with Lifecycle.lua alone omitted: Perf.lua's NEEDS_LIFECYCLE
floor is a silent return, not a raise, so Perf/PerfPanel stay in the
list and simply do not register (said in a comment). Asserts the
degraded instance is not the live one, runs the two-table
assertSurfaceParity against NS.Lifecycle with an empty ignore set (the
stub carries every live key, `name` included; the grep for the
addon's call sites is named in the comment), and adds the Slash case's
function-only reverse check. Header recounted to eight seams, and the
by-name/two-table paragraph says why Lifecycle uses the two-table
form.
- tests/run.lua: Kit.setSurfaceSource gains
["LibKa0s-Lifecycle-1.0"] = NS.Lifecycle.
- docs/testing.md: the degradation-stub section named four seams and
two by-name callers; it now lists all eight and which form each uses.
- docs/test-cases.md regenerated (921); README Tests badge 921/921.
Shown able to fail: with `LC.PrintHolds` deleted from the stub the case
went red with "Lifecycle stub: ... PrintHolds is missing (live:
function)"; reverted.
core/LifecycleSetup.lua and docs/module-map.md give no count, so they
are unchanged (their claim is now true).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 33b3f831b0e7567772f9fb93b96c11ad0525d861
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:46:48 2026 +0530
PM-12: Declare the bus messages through LibKa0s-Bus-1.0's Catalog
The three message constants are now declared once each through the
dot-called LibKa0s-Bus-1.0 Catalog, behind a new core/BusSetup.lua seam
(NS.BusLib). Catalog validates the declaration at load and answers a
strict table, so a mistyped key raises at the read instead of a
publisher silently sending nil (PanelMaster#52).
- core/BusSetup.lua: publishes the library table as NS.BusLib, or a
stub whose Catalog hands back the host's table unchanged (same wire
names, no strictness). Only Catalog is adopted; Bus:New and tracked
targets are not, and NS.NewBusTarget stays.
- PanelMaster.toc: BusSetup right after CoreSetup, with a load-bearing
comment (Registry.lua and Schema.lua call Catalog at file load).
- modules/Registry.lua: R.MSG = Catalog{PANELS, PANEL}; fire(MSG.*).
R.MSG_PANELS / R.MSG_PANEL deleted.
- settings/Schema.lua: S.MSG = Catalog{SETTINGS}; announce sends
S.MSG.SETTINGS. S.MSG_SETTINGS deleted.
- Every reader (Canvas:Enable, PanelEditor wirePanelsBus, comments in
Panel.lua/PanelEditor.lua/Canvas.lua, tests, rendering.md,
settings-panel.md) moved to the strict MSG.<KEY> read; the grep for
MSG_PANELS|MSG_PANEL\b|MSG_SETTINGS prints nothing.
- tests: red-first parity case for the Bus seam (ignore New; same wire
names on both arms), strict-read cases for Registry.MSG and
Schema.MSG, the degraded arm answering nil without raising, and a
TOC-order pin in test_harness. tests/run.lua registers
LibKa0s-Bus-1.0 as a surface source.
- Docs: ARCHITECTURE message-bus section, module-map row and load-order
bullet, adopted-majors count nine -> ten in CLAUDE.md and
module-map.md. test-cases.md regenerated; badge 920/920.
Deviations:
- core/BusSetup.lua added to test_libka0s.lua SEAM_FILES: the "seam-file
list covers every file that resolves a LibKa0s major" case requires
it; not named in the item.
- test_harness's TOC case only pinned presence, so the "TOC-order pin"
is a new order assertion (BusSetup before Registry and Schema).
- Item cited Canvas.lua:858-860; the subscriptions were at :917-919.
- Registry.lua grew four lines, so its line citations were rolled:
core/Database.lua (:200-202 -> :204-206), docs/smoke-tests.md
(:278-285 -> :282-289). The two .luacheckrc citations (:573, :576)
were already stale and now name the real lines (:517, :520).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit c8fca4caf38972fc8870eeef2af7d75981650dbd
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:39:47 2026 +0530
PM-11: Read the minimap row's CLI path as global.minimap.shown
launcher-§3 (standard v2.65.0, WS-06): the row's schema path is its CLI
name, so it reads in the row's own sense. S.MINIMAP_PATH is now
"global.minimap.shown"; the new S.MINIMAP_STORE = "global.minimap.hide"
is LibDBIcon's key and the only stored key. The row's get/set invert onto
the store, S:SnapshotPersisted still excludes the row by its path, and
S:Register's defaultsRoot answers no root for the row (the one
closure-backed row, architecture-§5) and checks the store against the
global defaults instead, counting one missing with a printed schema error
if it does not resolve. No `shown` key is ever written or declared
(anti-pattern #81). Comments in settings/Schema.lua and
core/LauncherSetup.lua rewritten to name the store.
No SavedVariables migration and no schema-version bump: the stored key
did not move. A test pins it: a legacy store { hide = true,
minimapPos = 200 } reads `get global.minimap.shown` as false, the button
stays hidden, minimapPos is untouched, and no `shown` key lands in the
raw store after a set.
Player-facing CLI rename, for the next Version History roll:
`/pm set global.minimap.hide <v>` became
`/pm set global.minimap.shown <not v>`; the old path now answers the
unknown-setting refusal ("Setting not found"), it is not an alias.
Tests (red first): the path pin, the /pm get/set echo case and the
legacy-store case in tests/test_launcher.lua; Register also asserted to
count an undeclared store. tests/test_schema.lua reads the minimap
default through the store and expects the new path in the Master
controls order. docs/ARCHITECTURE.md, docs/schema.md, a new smoke step
7b.8b, docs/test-cases.md regenerated, README badge 916/916.
Finding ids: none (item carries none).
Deviations: the item's line cites (:187, :530-539, :170-186, :516-529)
had drifted; the intended code was edited at its current location.
Added a smoke step 8b in section 7b, which the item's smoke checks
referenced but the doc did not yet carry.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 560e4d82b1badc8c48aab19f7bf7cf4f48976c92
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:35:22 2026 +0530
PM-10: address review — roll core/Database.lua line citations past the new comment line
dea8d67 added a comment line to core/Database.lua above InitDB, so everything
below it moved down by one. The citations of those lines now point at the new
positions:
- tests/test_database.lua:12 cites the RunMigrations call at :20 (was :19)
- docs/ARCHITECTURE.md:34 cites the AceDB:New open at :19 (was :18)
- docs/profiles.md:4 cites the AceDB:New open at :19 (was :18)
- .luacheckrc:152 cites the NS.Registry.ReloadProfile probe at :99 (was
:80). This one was already stale before dea8d67 (the probe sat at :97);
the fix is the same, so it goes in here too.
Comment and doc changes only. Lint 0/0; tests 914/0; no function above
CCN 15.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit dea8d6729ed6652b767e09d46abf052a63d5cffb
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:32:35 2026 +0530
PM-10: Declare schemaVersion 0 and migrate every stored profile
Migration stamp per WS-03 (savedvariables-§1, toc-file-§2, standard
v2.65.0): the runner owns the stamp, the defaults declare its floor.
- defaults/Global.lua: NS.defaults.global now declares schemaVersion = 0.
The "DELIBERATELY NOT SEEDED" block is replaced by the v2.65.0 reason:
0 masks no legacy account (an unstamped file reads 0 and the gate
opens), and a current-version default would be stripped by
removeDefaults and never persist.
- core/Database.lua: RunMigrations reads `tonumber(g.schemaVersion) or 0`
and returns early when current. The v1 -> v2 frame-name stamp is
extracted into stampFrameNames(profile) and now walks EVERY profile in
db.sv.profiles, plus db.profile when it is not among them (identity
check), because the account-wide stamp alone must not gate a
profile-scoped step. The stamp is written only after the step returns.
RunMigrations is CCN 6 (stampFrameNames 7, stampEveryProfile 6).
- RegisterProfileCallbacks comment: inactive profiles are stamped at
init; R.Sanitize stays the per-record repair for imported/copied
profiles. Stale sentences fixed (R-09): Database.lua "global holds only
the schema stamp", the [Init] example "schema v1" -> "schema v2", and
defaults/Profile.lua:4-5.
- Docs (A-06): ARCHITECTURE.md, common-tasks.md, module-map.md and
profiles.md now say Global.lua declares schemaVersion = 0 (the runner's
floor; the runner writes the real stamp) and LibDBIcon's minimap table.
docs/schema.md left as is. No Documented-deviations row: declaring 0 is
now compliance, which closes A-05 and A-17.
- Tests (red first): defaults declare schemaVersion 0; a legacy record in
a NON-active stored profile gets its frame name; the stamp lands above
the declared default. "stamps a version onto an unstamped DB" now
asserts the exact version; MigrationSummary expectation is v0 -> v2.
docs/test-cases.md regenerated and the README badge moved to 914/914.
Findings: PanelMaster-A-05, PanelMaster-A-06, PanelMaster-A-17,
PanelMaster-R-09.
Deviations: docs/settings-panel.md:321-324 repeated the callback comment's
reasoning, so it gets the same update (inactive profiles are migrated at
init); the item did not list it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 2568e655a2e6962a6d7abac3d15cd7a724494736
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:29:17 2026 +0530
PM-09: address review — module-map enUS row and localization paragraph
docs/module-map.md: the locales/enUS.lua row said it carries no keys;
it now carries the library-absent line Sl:LibraryAbsentLine formats.
docs/localization.md: split the paragraph so "a later pass can wrap
those labels" refers to the hardcoded labels again, reflow it, and name
every verb that prints the library-absent line — /pm lock and /pm unlock
when the Lock frame row is absent, and /pm enable and /pm disable when
even their write-through is refused (Sl:CliEnable), matching
locales/enUS.lua.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit b956b4bc25ab1fc82eb7d38f57c9a1828f75f481
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:25:37 2026 +0530
PM-09: Route library-absent enable/disable/lock/unlock per WS-02
The composed Master-controls rows (settings.enabled, state.locked) vanish
whenever the Options major is absent, on a fully library-less load and on
a partial load missing only Options. /pm disable and /pm enable then
printed the settings-CLI notice and left the latch up; lock/unlock did
the same with no library-absent line.
- settings/Schema.lua: pass writeThrough = { S.ENABLED_PATH } on the
descriptor (Schema minor 2, LK-23). hostSchemaStub builds the set and
one synthetic { path, writeThrough = true } row per path once in New;
Set and SetMany resolve a row-less listed path to that row, so it is
stored raw (copy, no validate/normalize/onChange) and announced with
the synthetic row. Every other row-less path is still refused.
Stub header comment updated.
- settings/Slash.lua: Sl:CliEnable (route a: CliSet when the row exists,
else write through, NS.RefreshEnabled(), FormatKV echo; the
library-absent line if even that is refused), Sl:CliLock (route b),
Sl:LibraryAbsentLine via NS.L. NS.COMMANDS enable/disable/unlock/lock
call them. The stale comment claiming announce("enabled") now names
NS.RefreshEnabled() and says the row does not announce (R-09).
- Slash degradation arm per LK-18's stub shape: Sl.DISABLED_LINE_FORMAT
published on both arms (live = lib.DISABLED_LINE_FORMAT), DisabledLine
formats from it; degraded PrintHelp prints the notice once then one
"/pm <cmd> <desc>" row per verb.
- locales/enUS.lua: the library-absent key, documented as the one string
routed through NS.L. ARCHITECTURE localization-§1 row, localization.md,
slash-dispatch.md ("Library-absent load"), module-map.md, smoke-tests.md
and locales/PostLoad.lua comment updated.
- Tests (red first): three degraded/partial cases in test_libka0s.lua,
two writeThrough cases in test_schema.lua, assertLibraryConstant in
the Slash parity case. test-cases.md regenerated; badge 906 -> 911.
Deviations:
- core/LifecycleSetup.lua: NS.RefreshEnabled moved above the Lifecycle
degradation branch, which returned before defining it; on a fully
library-less load it was nil, so route (a) (and the AceDB profile
callbacks) could not move the latch.
- The Slash stub's UNAVAILABLE text no longer claims the help index is
unavailable (it now prints one); the bare-/pm-without-config and
unknown-verb fallbacks print the degraded index instead of the notice
alone. The existing bare-/pm case was updated to match.
- The stub's writeThrough also covers SetMany (same list, same plan),
matching the library contract; the item named only R.Set.
- No tests/run.lua surface-source entry was needed: assertLibraryConstant
falls back to the mock LibStub.
Finding: PanelMaster-R-09 (the settings/Slash.lua:292-293 part).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 14f9656b91d0b090e5aae481860a96d03cb9c3e4
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:17:23 2026 +0530
PM-08: address review — module-map rows for SafeRegisterEvent and rejectedEvents
The core/CoreSetup.lua row now lists NS.SafeRegisterEvent among the seam's
exports, gives its degraded single-pcall rung, and records that
SafeRegisterUnitEvent and SafeRegisterEvents are deliberately not
re-exported. The core/State.lua row now lists the session-only
State.rejectedEvents, which the registration paths write and the debug dump
reads.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 8ccee1cef510eb59a211bf874e73fd931a49b6d7
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:14:22 2026 +0530
PM-08: Route every event registration through Core's SafeRegisterEvent
NS.StandUp's three registrations and OnInitialize's PLAYER_LOGIN were bare
RegisterEvent calls: an unknown name would raise out of the stand-up and
leave the later registrations, Canvas:Enable and the repaint unbound, with
no record anywhere (events-frames-taint-§1, finding PanelMaster-A-01).
- core/CoreSetup.lua: live arm republishes lib.SafeRegisterEvent (Core
minor 8) at column zero so the Core parity derivation checks it; the
degraded arm gets a one-rung pcall stub that appends a refused name once.
SafeRegisterUnitEvent / SafeRegisterEvents are not re-exported (no caller).
- core/State.lua: session-only State.rejectedEvents.
- core/LifecycleSetup.lua: NS.StandUp registers from a STAND_UP_EVENTS
table through NS.SafeRegisterEvent and logs NS.Debug("Events",
"rejected %s") on a false return. NS.StandDown keeps bare unregisters.
- core/PanelMaster.lua: PLAYER_LOGIN goes through the same helper.
- core/DebugLogSetup.lua: Diagnose ends with "rejected events: <n>
(<names>)" or "rejected events: 0", so /pm debug dump reaches the list.
- docs/debug.md, docs/ARCHITECTURE.md (Event Subscriptions): say so.
- tests/test_disabled.lua: red-first cases for the IsEventValid rung and the
C_EventUtils = nil rung (two stand-ups, one recorded name, dump line),
the empty-list dump line, and the degraded stub directly.
- tests/test_panel.lua: the F-013 source scan now matches the
SafeRegisterEvent(self, "PLAYER_LOGIN" form.
- docs/test-cases.md and the README badge regenerated (906).
Deviations: the three StandUp registrations are a loop over a local table
rather than three literal calls (same calls, same order, same logging).
The source scan in tests/test_panel.lua had to follow the new call form.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 49ea41abdfc6790f093e5ca57f24e486da43b588
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:08:12 2026 +0530
PM-07: Make C.MAX_GRID 64 and have the grid slider declare it
The Grid size slider's max was a literal 64 while its validate and the
drag clamp in modules/Unlock.lua read C.MAX_GRID, which was 128, so the
three disagreed on the largest grid. No UI or CLI path could ever store
more than 64 (the CLI clamps to the row's max), so the constant comes
down to 64 and the settings.gridSize row declares max = C.MAX_GRID: the
slider, the write seam and U.SnapPosition now share one maximum. A
hand-edited SavedVariables value of 65-128 snaps on a grid of 64 at the
next drag and is otherwise harmless; the Constants comment says so.
Tests (red first): test_schema "the grid-size slider and the write seam
share one maximum" and test_unlock "a grid above the slider's 64 snaps
on a grid of 64". The existing 99999 clamp case keeps its value (100 on
a 64 grid still lands on 128); its comment now names 64.
tests/test_constants.lua never pinned 128 for the grid, so nothing to
update there. docs/test-cases.md regenerated, README badge 902/902.
Finding: PanelMaster-R-07
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 3174cc9b8ee1da5974333475a04c075d5433be78
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:04:18 2026 +0530
PM-06: Keep the Panels page's per-panel Unlock tick on the real state
The per-panel Unlock checkbox read NS.Unlock:IsPanelUnlocked once at
build and had no refresher, so it could show a state the panel was not
in: a global unlock left it unticked (and unticking it did nothing), a
global lock cleared per-panel unlocks behind it, and a combat-deferred
tick replayed at PLAYER_REGEN_ENABLED left it unticked (PanelMaster-R-08,
review F-008).
- settings/PanelEditor.lua: the tick gets a scalar refresher that
re-reads IsPanelUnlocked and disables the box while the global unlock
is on (also set at build); the tooltip says why it is grayed out.
wirePanelsBus remembers its ctx in E.__ctx, and the new
E:RefreshUnlock runs NS.Helpers.RefreshPanel(ctx, false), the scalar
tier, which only repaints a shown page. No new bus message. File is
1487 lines (+11 net, budget 1488).
- modules/Unlock.lua: U:SetUnlocked, U:SetPanelUnlocked (non-deferred
path) and U:ResumePending end with a presence-guarded
NS.PanelEditor:RefreshUnlock() call (precedent modules/Registry.lua).
- tests/test_panel.lua: 'Panels page: the per-panel Unlock tick tracks
global, per-panel and deferred unlocks' covers (a) global unlock ticks
and disables the box, global lock clears and re-enables it, and (b) a
tick in combat is deferred and reads false, then OnRegenEnabled
replays it and the box reads true. Confirmed red before the change
("the tick does not show the global unlock").
- docs/test-cases.md regenerated, README badge 899 -> 900,
docs/smoke-tests.md section 9 step 11 gains the Lock frame / combat
checks.
Deviations: the tooltip says "Grayed out" rather than the item's
"Greyed out", because the localization-5 prose gate rejects British
spellings. E.__ctx is assigned before the once-only guard in
wirePanelsBus so it always names the registered page. The test points
E.__ctx at its own freshly built page context (restoring it after),
since the suite's page contexts are not the one P:Register wires.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 823985315903f7e34a1c21bbe592b38ad54e004a
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 08:59:07 2026 +0530
PM-05: Release mismatched frames before RenderAll renders any panel
Panel ids are per profile, so a profile switch can hand the same pair
of frame names to the same pair of ids the other way round. RenderAll
resolved each id one at a time: id 1 asked for the name still held by
active[2], found the pool empty, and CreateFrame'd a second frame under
that global name, orphaning one frame on every switch (PanelMaster-R-05).
- modules/Canvas.lua: RenderAll is now two passes over a file-local
scratch table `want` (id -> NS.Registry.FrameName(rec)), refilled in
place by fillWant so a rebuild allocates nothing. releaseMismatched
returns every active frame whose id is gone or wants another name to
the pool, and only then does each record Render. Render's single-id
mismatch branch stays, and its comment now calls it the fallback for
the per-id MSG_PANEL path. The pool comment says the one-frame-per-
name bound now holds across a name-swapping profile switch.
CCN: RenderAll 2, releaseMismatched 3, fillWant 3.
- tests/test_profiles.lua: 'Profiles: swapping frame names across ids
creates no second named frame'. Seeds P1 {1 = Alpha, 2 = Xray} and
P2 swapped, switches six times through OnProfileChanged, counts
named CreateFrame calls (0 after the first render), checks each name
resolves to Canvas:FrameFor(id), and that PooledCount never grows.
Confirmed red before the fix for the right reason (expected 0, got 6).
- docs/test-cases.md regenerated, README badge 898 -> 899;
docs/smoke-tests.md 12b-2 gains the swapped-names switch check.
Deviations: the test keeps the two profiles itself and swaps them the
way the mock's __switchProfile does (replace db.profile, fire
OnProfileChanged) rather than calling NS.db:SetProfile, because the
mock AceDB models one live profile table. The mock CreateFrame does not
bind _G, so the wrapper records each named frame in a local `globals`
table that stands in for _G (last CreateFrame wins, as in the client).
Scratch clearing uses a pairs() loop, not wipe(), which luacheck does
not know in this repo.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit cab60d8d2540017df2c554619b11f55825cb4478
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 08:01:47 2026 +0530
PM-04: Bound /pm recover in the panel's scaled units via EffectiveScale
applySpec calls SetScale before SetPoint, so a panel's stored x/y are in
its own scaled units (own scale x master scale). R:Recover clamped them
against Compat.GetScreenSize() in UIParent units, so at s=0.5 it dragged
a visible panel inward and at s>1 it left a genuinely lost one in place.
- core/Util.lua: Util.EffectiveScale(rec, settings) = own scale clamped
to MIN/MAX_PANEL_SCALE (template fallback) x master scale (nil, <= 0 or
non-number guarded to 1). Documented as the one definition render and
recover share (options-ui-§15); the master-scale guard comment moved
here from Canvas.
- modules/Canvas.lua: addGeometry sets spec.scale from EffectiveScale;
the local masterScale is deleted.
- modules/Registry.lua: R:Recover reads the settings once and bounds with
offsetRange(relPoint, w / s) / offsetRangeY(relPoint, h / s), with a
comment on why the offsets are in scaled units.
- tests: two Registry.Recover cases (scale 0.5 at 1.5 x screen width is
left alone; master 2 at 0.75 x width is moved to w/2), confirmed red
before the fix for the right reason; one Util.EffectiveScale case
(clamp bounds, master nil/0/negative/junk -> 1, the product). The five
scale-1 Recover cases and the test_canvas scale cases are unchanged.
- docs/test-cases.md regenerated, README badge 895 -> 898;
docs/schema.md explains the scaled-unit bound; docs/smoke-tests.md §10
gains the Master scale 0.5 / 2 steps.
Finding: PanelMaster-R-04.
Deviation: the settings lookup (NS.db and ... or {}) lives in a small
local currentSettings() rather than inline in R:Recover. Inline it took
R:Recover to CCN 15 (at the cap); with the helper it stays at 12.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube
commit 9a85d626347fa0238740b9c35616aa83da7bd1df
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 07:56:29 2026 +0530
PM-03: Flip combat visibility at combat start from the REGEN event
"Only in combat" and "Only out of combat" never flipped at the pull:
Compat.InCombat() asked InCombatLockdown, which starts after
PLAYER_REGEN_DISABLED, so OnRegenDisabled rebuilt every spec with
inCombat=false and the out-of-combat look held for the whole fight.
- core/Compat.lua: Compat.InCombat prefers UnitAffectingCombat("player")
(presence-guarded), falls back to InCombatLockdown, else false.
Comment rewritten: display reads the combat flag
(events-frames-taint-§2); lockdown starts after REGEN_DISABLED.
- modules/Canvas.lua: Render(id, inCombat) defaults a nil inCombat to
NS.Compat.InCombat(); RenderAll(inCombat) and RenderForCombat(inCombat)
thread it through. BuildSpec stays pure.
- core/PanelMaster.lua: OnRegenDisabled -> RenderForCombat(true);
OnRegenEnabled -> ResumePending, then RenderForCombat(false).
- modules/Unlock.lua: unchanged gate; SetUnlocked comment says why it
keeps asking InCombatLockdown (a lockdown question, not a display one).
- .luacheckrc: UnitAffectingCombat in read_globals (test_lintconfig does
not pin the list, so nothing to extend there).
- tests/test_canvas.lua: the combat case now delivers OnRegenDisabled
with the flag still false (client order) and a mirrored inCombat case
was added, both marked "red under: drop the explicit inCombat argument
from OnRegenDisabled". Confirmed red before the fix and red again with
the argument dropped.
- tests/test_compat.lua: three InCombat cases (flag vs lockdown diverged
locally in the case, the lockdown fallback, both APIs absent). The kit
mock is untouched.
- docs: smoke-tests §8 gains the Only-in-combat / Only-out-of-combat pull
checks; ARCHITECTURE, data-flow and performance event tables show the
explicit argument; test-cases.md regenerated (895) and README badge.
Findings: PanelMaster-R-03, PanelMaster-R-06.
Deviations: the ARCHITECTURE / data-flow / performance event-table
updates are not named in the item; they keep the docs matching the code.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube
commit af56239578386232f2b30af4663c90d223f97d9f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 07:51:14 2026 +0530
PM-02: Strip the unlock overlay while stood down, and test the routes
Canvas:Render read the stand-down latch only to set spec.shown = false,
then called NS.Unlock:Decorate unconditionally. Decorate shows an
unlocked panel regardless of spec.shown and arms drag on it, so a
disabled addon still drew, outlined and let the player drag every
unlocked panel (and a drag wrote db.profile.panels while the addon was
off). That broke slash-commands-§7's "disabled is total".
Render now reads the latch once. Stood down, it calls
NS.Unlock:StripOverlay (hidden, mouse-transparent, not movable) and
Decorate never runs; otherwise Decorate runs as before. The session
unlock state (NS.State.unlocked, unlockedPanels) is untouched, so
NS.StandUp -> RenderAll decorates again from current state
(performance-§6). No imperative hide or force-lock was added to
NS.StandDown (anti-pattern #85). The stand-down rung comment and the
header note on the method-presence guards now cover both branches.
Render stays at CCN 13.
Test first: "Disabled 5b" in tests/test_disabled.lua drives route A
(unlock, then disable), route B (disabled, then the state.locked row and
`/pm set state.locked false`) and route C (disabled, then a per-panel
unlock). It asserts no panel is shown and none takes the mouse, then
re-enables and asserts both panels come back shown and draggable. Before
the Canvas change it went red with shown = 2/2/2/1 for A/B-schema/
B-slash/C. It carries the "red under" line.
docs/test-cases.md is regenerated (891), the README badge is bumped to
891/891, and docs/smoke-tests.md §7 gains step 13 (unlock, then disable;
untick Lock frame and tick a panel's Unlock while disabled; enable).
Findings: PanelMaster-R-01, PanelMaster-R-02.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube
commit 3abaa9008756dfc856efa489db24c6400698786d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 07:46:59 2026 +0530
PM-01: Bring the Schema stub to v1.56.0: normalize, id forwarding, tests
The host degradation stub in settings/Schema.lua (hostSchemaStub) now
matches LibKa0s-Schema-1.0 minor 2 on everything but the log and tally:
- prepare() runs row.normalize(value, rid) after validate and before the
nowhere-to-store refusal; the returned value is what gets stored, and a
nil answer refuses as `false, "invalid value", why` (Set) or
`false, "invalid value", why, i` (SetMany), nothing stored.
- R.Get(path, id) hands id to row.get; R.ApplyDefault(row, id) forwards
id to R.Set (LK-22 R-14 parity).
- The header comment names SetMany, normalize and the id forwarding, and
cites docs/api/Schema/version-2-docs.md.
SetMany itself (and the prepare/commit split) landed in PM-00; verified
here, not redone. Every stub function stays at CCN 10 or below.
Tests (tests/test_schema.lua), on degraded arms built with
tests/degraded_env.lua loadPartial({ Schema = true }):
(a) SetMany stores every entry in order and runs each onChange
(b) SetMany is all-or-nothing (gridSize 999 -> false, "invalid value",
nil, 2; entry 1 unstored; no onChange)
(c) SetMany with opts.act runs inside one bracket
(d) the live runtime and the stub answer SetMany identically (answers,
arity and stored values over three batches)
plus two for the new behavior: row.normalize (replace / refuse) and
Get/ApplyDefault id forwarding. The normalize and id cases were red
first (7.6 stored unnormalized; row.get got nil). (a)-(d) were checked
red by deleting R.SetMany from the stub in a scratch copy ("attempt to
call field 'SetMany'", and the surface parity case red), as the
"red under" comment says.
docs/test-cases.md regenerated (884 -> 890) and the README Tests badge
rolled with it. The regeneration also restores the section sign in
three kit case names (localization-§5, layout-§1) that the previous
inventory had without it; that is the runner's own output.
Deviations: (a)-(d) were not red before this item's stub change, because
PM-00 already added SetMany; the red was confirmed by deletion instead.
PM-00's phase 2 order (every store, then every onChange, the live
commitBatch order) is kept rather than the item's per-plan store+onChange.
No other PanelMaster red from the LK dry-runs remained after RV-PM/PM-00.
Findings: none (the item resolves no finding ids).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube
commit 3a09ad830e42102de71811ce418a221cd81a3efc
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 07:42:12 2026 +0530
PM-00: Give the Schema degradation stub SetMany, clearing the RV-PM red
RV-PM re-vendored LibKa0s v1.56.0 and recorded one red:
Parity: the Schema seam's degraded surface matches the live one, on
both levels -- schema instance vs host stub: SetMany is missing
(live: function)
Schema minor 2 added SetMany to the live instance; hostSchemaStub() in
settings/Schema.lua did not have it.
This does the "stub gains SetMany" part of PM-01 here, as PM-00 directs:
- R.Set's body is split into local prepare (find target, validate,
refuse nowhere-to-store; answers a plan or nil, err, why) and small
store / react / announceOne helpers. Set's observable order is
unchanged: refuse, validate, store, react, announce.
- New R.SetMany(entries, opts): phase 1 prepares every entry and
answers false, err, why, i on the first refusal (unknown path or
invalid value) with nothing stored; phase 2 stores and runs onChange,
inside R.BulkRun when opts.act is set; then d.announceBatch once when
the host has one, else d.announce per write.
Left to PM-01 (it will find the above done): row.normalize in prepare,
id forwarding on R.Get / R.ApplyDefault, the header comment naming
SetMany and normalize, and the test cases (a)-(d) in tests/test_schema.lua.
Deviation from PM-01's text: phase 2 runs every store and then every
onChange (the live Schema.lua commitBatch order, so a reaction reading a
sibling row sees the whole batch), rather than store+onChange per plan.
The helper is named announceOne, not announce, because a file-level
local announce already exists (lint W431 shadowing).
Suite (all bounded): tests/run.lua 884 passed, 0 failed (the parity case
green); lint 0 warnings / 0 errors in 60 files; the CCN 15 complexity
run prints nothing (largest new function prepare, CCN 7); no authored
.lua file over 1500 lines. No tests/perf.lua.
Findings: none (the item resolves no finding ids).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube
commit b26ab40f6c7c8a9ddbae381aa7504b9dd7ea18a6
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 04:40:51 2026 +0530
RV-PM: Re-vendor LibKa0s v1.56.0 and record its delta bundle
Replace libs/LibKa0s/ and tests/_kit/ whole from the local tag v1.56.0
(tag 4622018 -> commit 514fc0a), extracted with git archive, and roll the
CLAUDE.md provenance line 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, Perf 13); the kit goes
from revision 25 to 26 and gains asserts.lua, mock_events.lua and
prose_lists.lua. Both payloads diff empty against the tag, with and
without --strip-trailing-cr; the runner keeps mode 100755.
Adds the frozen bundle docs/revendor/2026-09-23-v1.56.0/ (01_DELTA.md,
05_SUMMARY.md), written by hand from the local wow-addon
revendor-libka0s.md as amended by WA-01: base, per-file minors, both
payload diffs, kit pairing 25 -> 26, the consumption map and the
contract delta. No contract blocker. Adoption is left to the M3 items.
Suite after the copy (all through ka0s-bounded):
- tests/run.lua: 883 passed, 1 failed, 0 skipped, 884 total (baseline
884/884). The one red is caused by the stricter kit/library, as the
item permits:
Parity: the Schema seam's degraded surface matches the live one, on
both levels -- schema instance vs host stub: SetMany is missing
(live: function)
PM-01 clears it (the Schema stub gains SetMany).
- luacheck: 0 warnings / 0 errors in 60 files.
- lizard CCN 15 warning run: nothing above 15; largest authored file
1476 lines.
docs/test-cases.md and the README test badge are left stale on purpose
(kit case names now carry the section sign); PM-DOCS regenerates them.
The span back-fill of unrecorded tags is PM-18, not written here.
Findings: none (the item resolves no finding ids).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube
commit 7183100ee4f6ca8a2a9989119bdf342a3406b52e
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 20:50:41 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 ce0b70501f420333d934e2ed150c01876ab046fc
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 19:09:11 2026 +0530
Count Schema among the adopted LibKa0s majors in CLAUDE.md
The v1.55.0 pass made LibKa0s-Schema-1.0 the settings runtime, but the
agent brief still said eight of twelve majors were adopted. The vendored
library ships fifteen, and nine are consumed here, which is what
docs/module-map.md already says.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx
commit ce0b70501f420333d934e2ed150c01876ab046fc
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 19:09:11 2026 +0530
Count Schema among the adopted LibKa0s majors in CLAUDE.md
The v1.55.0 pass made LibKa0s-Schema-1.0 the settings runtime, but the
agent brief still said eight of twelve majors were adopted. The vendored
library ships fifteen, and nine are consumed here, which is what
docs/module-map.md already says.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx
commit c595035cc0fb9dcde61ab8add3db43a6eebdc7ac
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 16:54:43 2026 +0530
Pin the player's JC-5 path and name the walk case for what it asserts
The case that drives the library's RestoreDefaults("general") walk still
claimed the General page's Defaults closes the console; that button is the
profile reset and never writes the row. Rename it, and add the path a player
actually meets: /pm reset state.debugConsole through NS.Slash:OnSlash, which
closes the console (the row and the window). Dropping
defaults.debugConsole = false turns both red.
Bring the v1.55.0 bundle's summary in line with its corrected in-game check,
rewrap its long prose lines, and roll test-cases.md and the badge to 884.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx
commit 9923388de7604c6ffe04f64d16da537c94ef4daa
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 16:51:17 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 b473776a58fc083c599e7174095c4c29591f63a0
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 15:34:00 2026 +0530
Correct the in-game check that expected Defaults to close the console
The General page's Defaults button is the profile reset (P:RestoreDefaults
through ConfirmResetAll to db:ResetProfile). It never writes the
session-only state.debugConsole row, so an open console stays open, at
b7edc9f and now. The check asked the owner to expect the opposite.
JC-5 lives on the row reset instead: /pm reset state.debugConsole closes
the console, and with defaults.debugConsole = false dropped it does not.
The summary's check is split into that step and the minimap step that
survives Reset all settings. The same claim is corrected in
03_DECISIONS.md and in the settings/Schema.lua comment (comment only).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx
commit 46b86e2431c7bcbb84d3888096cc87d545ac646b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 15:21:49 2026 +0530
Record the v1.55.0 adoption pass, and roll the test inventory to 883
docs/revendor/2026-09-23 gains 02_CANDIDATES through 05_SUMMARY. Schema
was adopted (d830303, af8a935). The Bus Catalog was deferred as optional
(#52, state:triaged) and Compat was declined as a structural misfit (#53,
state:will-not-do). docs/test-cases.md is regenerated and the README
badge follows it.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx
commit af8a935830c8e2e5533c1fe81fea1ea83f390db4
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 15:19:44 2026 +0530
Adopt LibKa0s-Schema-1.0 as the settings runtime, keeping every seam name
settings/Schema.lua keeps its rows and builds one LibKa0s-Schema-1.0
instance (NS.SchemaRuntime) for the path walk, the row index, the write
seam, the bulk bracket and the boot shape check. NS.Schema:Set, :Get,
:FindRow, :Default, :Register and S.BulkBegin/BulkEnd/BulkLine delegate
to it, so no caller moved. The Options and Slash descriptors take the
instance's members as values.
- The minimap inversion leaves the seam and becomes the composed row's
own get/set, so nothing sits in front of Set.
- The composer's defaults gain debugConsole = false. The runtime reads a
nil default as "no restore", and the General page's Defaults has
always closed an open console.
- The refusal texts stay "unknown path: <path>" and "invalid value",
through a plain-table descriptor L.
- Register is Validate with a global-aware defaults root. It now counts
shape errors as well as unresolved paths.
- The profile reset's snapshot count stays host-side, as the design
allows.
Without the library the seam falls back to hostSchemaStub, which is
write-completing and log-silent and stands in for both the library and
the instance. The parity suite pins both levels, and test_schema drives
one degraded write per writer kind: /pm set and /pm disable, Reset All,
the page Defaults and a Registry bulk act. The six contract cases from
the previous commit pass unchanged. Two tests that appended a probe row
by hand now go through AddRows and Reindex, and the bracket-depth checks
read InBulk().
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx
commit d8303035765ab9867b8920f277919ee6b6375e19
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 15:10:13 2026 +0530
Pin the schema write seam's contract before the library takes it
Six cases in tests/test_schema.lua, each green against the host's own
S:Set / S:Get: the refusal texts and arity, a write answering exactly
true, the [Set] line before onChange, a raising onChange propagating
after the store, an interior-path read answering the stored table, and
the General page's Defaults closing an open debug console (the row
declares no default today).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx
commit b7edc9f663cf43ab15ebe46c65a3f73a23269690
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 14:55:43 2026 +0530
Re-vendor LibKa0s v1.55.0, and hand the cap gate to the kit
Both payloads copied whole from the v1.55.0 tag with the CLAUDE.md
provenance line rolled in the same commit. No existing file's minor
moves; Compat, Bus and Schema arrive as new majors and are not adopted
here. Kit revision 25 ships the layout-1 cap gate, so the local
tests/test_layout_cap.lua and its bare suite entry are retired in favor
of the kit's pair-form declaration.
The census is renamed to "Files over the 1500-line cap" and moved under
Documented deviations, where the kit's gate reads it, stating that
nothing is over the cap today. The 1000-1500 band leaves the hub for
the release watch list, which already dispositions all four band files.
The delta read is recorded in docs/revendor/2026-09-23/01_DELTA.md.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx
commit eb4b4a84235253c2611a31854b757f65b18df4d5
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 11:33:56 2026 +0530
Bring .gitattributes to the line-endings-§5 canonical body (standard v2.63.0)
The client-bound body now carries the `*.py text eol=lf` carve-out and
the shebang-file comment block that replaced the shell-only wording.
The path-keyed appendix for tools/artwork/bin/realesrgan-ncnn-vulkan
is kept unchanged below the body, so the file still diffs clean against
the canonical text plus a conforming appendix.
The four tracked .py files under tools/artwork and tools/sunn were
already stored LF in the index; their CRLF working copies were
re-checked-out so the tree agrees with the new pin. No content change,
nothing renormalized in the index.
The rest of the standards reference was already current: X-Standard,
the bare README badge and the CLAUDE.md compliance block all match, and
the retired-notation sweep finds no hits outside frozen bundles.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx
commit e30e329557d7dee0e5af467927444042c21c2b3a
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 22 21:05:05 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 ff4bef0467b00a49d787180565adbbe8bf63836e
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 22 19:38:47 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 78f751587ba32aaccb08f09665b647dfa5e39121
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 22 18:06:29 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 f2b08e28b01ad05523d9dd3ba06fe7e05c0b043c
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 22 17:12:17 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 9e024d559da5ecd7787b026489fbc58c3143925b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 22 10:22:38 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 61 files; 849 passed, 0 failed, 0 skipped, 849 total
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk
commit c8d924f814818ddae500e95c0f97fe51109d19a2
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 22 02:25:12 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 61 files; 849 passed, 0 failed, 0 skipped, 849 total
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk
commit 10e66102a106f3106f67041f3ce380fd06fbc49f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Mon Sep 21 14:56:04 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, from v1.50.0.
No surface this addon uses changed, so there is nothing to adopt:
v1.50.0's member manifest is identical to OptionsWidgets minor 26's, and
the four O.IdList follow-ups behind it are fixes rather than new surface.
Gate: lint 0 warnings / 0 errors in 61 files; 849 passed, 0 failed, 0 skipped, 849 total
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk
commit cdc13ffc25743a61b515861c570097cb764f6466
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 20 19:56:23 2026 +0530
Re-vendor LibKa0s v1.47.0
OptionsWidgets minor 24: O.IdList takes a `columns` count, packing entries
row-major (1 2 / 3 4) into a Flow row, clamped to ID_COLUMNS_MAX of 2. Default
1 draws exactly what minor 23 drew, so a spec that never heard of the option is
unchanged. An entry with a note still takes a full-width row of its own, and
above one column an entry name no longer wraps -- it truncates from the tail,
which is where the gray `(id)` sits.
Not adopted, and there is nothing here to adopt it into: this addon builds no
id list. The only mention of the surface in authored code is the inert stub in
`settings/OptionsSetup.lua:92`, which exists for the surface-parity case -- its
own comment says "No page in this addon builds one, so each is INERT". Panels
are managed through the Panels editor and the registry, not through a typed-id
list, so no call site exists to widen and no new test was warranted.
OptionsWidgets.lua is the only payload file that moved; the kit stays at
revision 23 and the runner keeps mode 100755. The CLAUDE.md provenance line
moves in this commit with the bytes. No other file in the repo stamps the
vendored version -- `docs/data-flow.md:193` names v1.46.1 as the release the
combat lock shipped in, which is history and stays put.
Battery: 849 passed, 0 failed, 0 skipped (vendor-sync compared against
v1.47.0); lint 0/0 over 61 files; docs/test-cases.md regenerates byte-identical.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk
commit cdc13ffc25743a61b515861c570097cb764f6466
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 20 19:56:23 2026 +0530
Re-vendor LibKa0s v1.47.0
OptionsWidgets minor 24: O.IdList takes a `columns` count, packing entries
row-major (1 2 / 3 4) into a Flow row, clamped to ID_COLUMNS_MAX of 2. Default
1 draws exactly what minor 23 drew, so a spec that never heard of the option is
unchanged. An entry with a note still takes a full-width row of its own, and
above one column an entry name no longer wraps -- it truncates from the tail,
which is where the gray `(id)` sits.
Not adopted, and there is nothing here to adopt it into: this addon builds no
id list. The only mention of the surface in authored code is the inert stub in
`settings/OptionsSetup.lua:92`, which exists for the surface-parity case -- its
own comment says "No page in this addon builds one, so each is INERT". Panels
are managed through the Panels editor and the registry, not through a typed-id
list, so no call site exists to widen and no new test was warranted.
OptionsWidgets.lua is the only payload file that moved; the kit stays at
revision 23 and the runner keeps mode 100755. The CLAUDE.md provenance line
moves in this commit with the bytes. No other file in the repo stamps the
vendored version -- `docs/data-flow.md:193` names v1.46.1 as the release the
combat lock shipped in, which is history and stays put.
Battery: 849 passed, 0 failed, 0 skipped (vendor-sync compared against
v1.47.0); lint 0/0 over 61 files; docs/test-cases.md regenerates byte-identical.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk
commit 940bb11223943939d8de321d898c1d7a048543cd
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 20 02:27:21 2026 +0530
Align the version to the 1.1.1 tag; document the settings combat lock
The published 1.1.1-release tag sits on a rebuild of 1.1.0 while the TOC
and NS.version still read 1.1.0. Bump both (and the strings the smoke
tests and a Database.lua comment quote) to 1.1.1, and record 1.1.1 in
Version History as a re-triggered build with no functional changes. The
unreleased work since the tag stays out of that row.
The README Troubleshooting table and docs/smoke-tests.md had nothing on
the LibKa0s v1.46.1 settings combat lock: add a Troubleshooting row and
a combat-gating smoke step (§ 8 step 7).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WkU3isSkvWPZkWVr51uZKo
commit 47cda865b268965f83796c071fec098399e4a241
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 20 02:13:02 2026 +0530
Sync docs: options-page combat lock, Compat class color
data-flow.md's combat-gating section described only the /pm config
refusal; LibKa0s v1.46.1 (Options minor 22) now also covers a page that
is on screen in combat and refuses writes until PLAYER_REGEN_ENABLED.
The compat-layer row in ARCHITECTURE.md still listed class color as
Compat's, which LibKa0s-Core minor 7 took over (core/Compat.lua:84-94).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WkU3isSkvWPZkWVr51uZKo
commit 11e3d562b24c05bd949476b7d5f3a59764426133
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 19 21:47:16 2026 +0530
Re-vendor LibKa0s v1.46.1
The combat lock (standard v2.60.0, options-ui-§2/§13): a settings page
shown in combat is covered and refuses writes, Defaults and tab
switches until combat ends; the library never closes Blizzard's
settings window from addon code. v1.46.1 registers its combat events
only while a page is on screen.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WkU3isSkvWPZkWVr51uZKo
commit 11e3d562b24c05bd949476b7d5f3a59764426133
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 19 21:47:16 2026 +0530
Re-vendor LibKa0s v1.46.1
The combat lock (standard v2.60.0, options-ui-§2/§13): a settings page
shown in combat is covered and refuses writes, Defaults and tab
switches until combat ends; the library never closes Blizzard's
settings window from addon code. v1.46.1 registers its combat events
only while a page is on screen.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WkU3isSkvWPZkWVr51uZKo
commit 47dd30555bf1ce9ef128b095880a2c21b17fb374
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 19 16:32:24 2026 +0530
Re-vendor LibKa0s v1.45.0
OptionsWidgets minor 22 (LibKa0s-Options-1.0 21.22.1.7.3): the opt-in row field shownWhen draws a
row only while a selector path holds a given value, and re-renders the page once, on the next
frame, when the selector changes. Absent, a render is unchanged; this addon does not use it (see the
adoption sweep in Aura Master's docs/superpowers/plans/2026-09-19-smoke-feedback.md, Task 17).
Every other payload file is byte-identical to v1.44.0; the kit stays at revision 23.
Battery: 849 passed, 0 failed, 0 skipped (vendor-sync compared against v1.45.0); lint 0/0;
complexity check no new warning; perf none.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019uT32jXujZ279wBVAwHhEU
commit 47dd30555bf1ce9ef128b095880a2c21b17fb374
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 19 16:32:24 2026 +0530
Re-vendor LibKa0s v1.45.0
OptionsWidgets minor 22 (LibKa0s-Options-1.0 21.22.1.7.3): the opt-in row field shownWhen draws a
row only while a selector path holds a given value, and re-renders the page once, on the next
frame, when the selector changes. Absent, a render is unchanged; this addon does not use it (see the
adoption sweep in Aura Master's docs/superpowers/plans/2026-09-19-smoke-feedback.md, Task 17).
Every other payload file is byte-identical to v1.44.0; the kit stays at revision 23.
Battery: 849 passed, 0 failed, 0 skipped (vendor-sync compared against v1.45.0); lint 0/0;
complexity check no new warning; perf none.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019uT32jXujZ279wBVAwHhEU
commit 82a7f8017ab4fd9f20c9e91e479e9ec7b4d5914d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 19 09:58:46 2026 +0530
Re-vendor LibKa0s v1.44.0
OptionsWidgets minor 21 arrives (opt-in removeStyle = "icon" on O.IdList);
every other major is byte-identical to v1.43.0. Test kit stays at revision
23 (byte-identical, no changes).
Battery: lua tests/run.lua 849 passed, 0 failed, 0 skipped (vendor-sync ran
for real and passed); lint 0 warnings / 0 errors; complexity check clean,
no new function above CCN 15; no tests/perf.lua in this repo.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019uT32jXujZ279wBVAwHhEU
commit eaa7807510620a557e7879ada66ff6e872aba068
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 17 20:19:02 2026 +0530
Re-vendor LibKa0s v1.43.0: kit revision 23 bounds every run and stops holding built instances
The kit now re-launches each run under a depth limit, a systemd scope
memory cap, ulimit -v and a timeout, and holds every case to a heap
budget, a leak gate and a CPU ceiling. Its mock no longer keeps every
instance a case built alive. The library payload is byte-identical.
DEPENDENCIES.md re-points its tests/_kit/framework.lua line citations.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qy4TpGt4ZzGBCHP5hejntU
commit d5ed125ea433b4d008597645192fe54b7577d053
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 17 18:33:44 2026 +0530
Disabling the addon stands it down, and a perf run takes the same latch
Adopts LibKa0s-Lifecycle-1.0 (vendored from LibKa0s v1.42.0) the way the rest
of the collection already has: core/LifecycleSetup.lua owns the one latch with
its two holds — the stored `disabled` state and a perf run — and a disabled
addon registers nothing, runs no timer, draws nothing and writes nothing from a
game event. The slash dispatcher and settings registration stay live, so every
reserved verb, `config` and the schema CLI still answer while disabled
(slash-commands-§2/§7 as of standard v2.58.0).
tests/test_disabled.lua is the conformance suite, over the kit's new
mock_record.lua recording registry. Suite 834 -> 849, badge and
docs/test-cases.md with it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FBmHJjW22defmzscncENmu
commit 8181d1d767bea5ef55cb29d0b6b3b367bdbffbd3
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 16 19:45:46 2026 +0530
Record the four-suite run of 2026-09-16
The battery had not run since this morning, so the record lagged every commit of
today's launcher cycle. This is that run: the frozen bundle, its ANALYSIS.md and
the row prepended to RESULTS.md.
Generated by tests/_kit/run-automated-tests.sh. The watch list's Disposition
column is the only authored cell in the file (automated-tests-§4).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019r6eqKPKL93nb93aiiZwsh
commit 3c4005abd6ae7266f56c289b9f78b910b032665d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 16 18:08:00 2026 +0530
The Master controls comment counts its own rows correctly
One comment block gave three different numbers for the same tab. It said the
composer exists because addons "were about to hand-write the same eight rows",
then said a library-less install loses "these six rows ... all six are the
composer's". The tab holds SEVEN, pinned by tests/test_schema.lua:267 and stated
correctly in docs/ARCHITECTURE.md -- so the prose disagreed with the test, the
docs and itself.
Both numbers were defensible once and neither is now. Eight is the canonical set
at its fullest, and this addon takes seven of them: it is exempt from the Test
mode row under options-ui-§15, unlocking being its preview. The comment now says
both, in that order, so the next reader is not left deriving which number the
sentence meant.
Also: "Nine addons" is eleven.
Comment only; no behaviour. 834 passing, lint 0/0 in 59 files.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019r6eqKPKL93nb93aiiZwsh
commit b6d69abe9d7191fb634861270d75e4ee530d0394
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 16 17:55:55 2026 +0530
Two documentation rows that had stopped describing the tree
THE VERSION HISTORY'S 1.1.0 ROW WAS THE ODD ONE OUT. Every highlight in the
1.0.0 row leads with a bullet; 1.1.0's five highlights were bare `<br>`-joined
sentences, so the table rendered one release as a list and the other as a wall.
Nothing about the entries changed -- the same five lines, punctuated the way the
row above them already was. A reader comparing two releases should be comparing
the releases, not parsing two different notations for the same thing.
THE LAYOUT CENSUS NAMED THE WRONG RUNNER-UP. `## Files by the layout-§1 band`
closes by saying which file is nearest the 1000-line band without being in the
table, and it said `modules/Registry.lua` at 937, sixty-three lines off. It is
not: `tests/test_libka0s.lua` is at 971 and `tests/test_sunnart.lua` at 955,
both nearer, and the first is twenty-nine lines from earning a row. The census
header is dated today, so a stale runner-up under a fresh date is worse than no
sentence at all -- it reads as measured.
WHY THIS ONE SLIPS AND KEEPS SLIPPING. `tests/test_layout_cap.lua` asserts the
table's MEMBERSHIP in both directions and nothing else, deliberately: a figure
in that column is a measurement, not a claim. The consequence is that the prose
around the table has no gate at all, and the prose is the half that names a file
the table does not contain. The `M4-18` note about Registry being trimmed under
the trigger is kept -- it is still true and still the reason that file is worth
mentioning -- but it is no longer doing duty as the nearest-file claim.
834 headless cases, luacheck 0/0, both vendor diffs empty.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019r6eqKPKL93nb93aiiZwsh
commit da7a902170e12b49047e7430479c10e682361c22
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 16 16:40:07 2026 +0530
A disabled addon refuses its feature verbs, from one place
slash-commands-§2 has carried a trailing SHOULD since it was written -- a
disabled addon answers a feature verb by saying so and naming `enable`, rather
than acting -- and no addon in the collection implemented it. Standard v2.54.0
made it precise enough to implement and audit, and this addon takes it: eight of
its nineteen verbs create, delete, rename, list, edit, unlock, lock or recover
the panels it is currently standing down from drawing, and a silent no-op on any
of them leaves the player with no clue why nothing happened.
THE GATE IS ON THE VERB TABLE, NOT ON THE VERBS. A guard pasted into each handler
is eight places to keep in step and a ninth to forget, and the next verb added
forgets it BY DEFAULT -- the wrong default for a courtesy nobody will notice is
missing. NS.COMMANDS is the one seam every verb passes through: the library's
dispatcher reads entry[3] out of that very table, and so does the degraded arm's
own run(). So settings/Slash.lua walks it ONCE, before either reader exists, and
wraps every handler whose name is not in ALWAYS_LIVE. One place, both surfaces,
and a verb added tomorrow is gated the day it lands.
ALWAYS_LIVE IS THE STANDARD'S OWN SET, spelled as data rather than as a chain of
conditions: help config version enable disable debug perf get set list reset
resetall. The reasoning is the standard's -- a player must be able to read and
repair settings and reach the panel while the addon is off, which is precisely
when they are most likely to need to, and enable above all or the pair is one-way
again. `perf` is listed although this addon registers no such verb: the set is the
rule rather than an inventory of today's table.
ONE TAGGED LINE, and it is the first string in this addon to route through NS.L.
locales/enUS.lua declares the key, which is the English source string
(localization-§1/§2), and the slash command is a `%s` rather than part of the key
so a translator never retypes a command -- the placeholder is a contract, since a
translation that drops it loses the one thing the line exists to name.
FIVE CASES, and three of them read the WORLD rather than the chat, because a case
that only checks the message passes over a verb that printed and then acted
anyway. The refusal loop is derived from NS.COMMANDS rather than from a list
written out beside it, so it covers the next verb too. The acting case drives
new / panel / rename / unlock / delete while disabled and reads the registry and
the unlock state back, then re-runs delete once enabled to prove the gate is a
gate and not a removal. Mutating the wrapper to print-and-fall-through reddens
two; widening ALWAYS_LIVE by one verb reddens two others.
834 headless cases, luacheck 0/0.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019r6eqKPKL93nb93aiiZwsh
This mod has no additional files

