1.1.0-release
What's new
tag dd67944d68dbef4fe3b5dd3f0088dbc7ad83c4de 1.1.0-release
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 03:40:18 2026 +0530
commit fa8f2726372a2675872f0d2645969aaaac0e047b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 03:07:42 2026 +0530
Release 1.1.0: version bump, release notes and the gated release run
Release gate (docs/automated-tests/20260927-030324/manifest.json, measured
692cec2, clean, --release 1.1.0), all five conditions PASS:
- Lint: pass, 0 warnings / 0 errors in 75 files
- Tests: pass, 383 passed / 0 failed / 0 skipped of 383
- Perf: pass, 9 scenarios
- Complexity: pass (lizard 1.24.0), 9976 NLOC, 1318 functions, avg CCN 2.1
- CCN <= 15: 0 warnings, max CCN 14; 0 files in the 1000-1500 band
Version 1.0.1 -> 1.1.0 in PartyFrameEnhanced.toc, core/Namespace.lua,
the pinned version tests (tests/test_envsetup.lua, tests/test_slash.lua),
docs/smoke-tests.md, docs/testing.md, docs/automated-tests/README.md and
docs/scope.md. docs/ARCHITECTURE.md build status names 1.1.0 as the latest
release and what it adds over 1.0.1.
README Version History gains the 1.1.0 row (out-of-range fade with the
Fade with party frames toggle, raid markers above the border and on pets,
the minimap button's status tooltip and click actions, /pfe diagnostics
and the Reporting a bug section, the shown-only Size & Position settings
and the combat lock). Older rows untouched.
Release bundle docs/automated-tests/20260927-030324/ with its ANALYSIS.md,
and the RESULTS.md row. The watch list is empty (no function over CCN 15,
no file in either layout band), so no disposition was owed.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 692cec2e306e6b8bde3c0d65dd7bb4a040cf2a7d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 03:03:17 2026 +0530
README: Usage as the three-step setup flow, and sync-docs
Usage is restructured as the three-step setup flow. How it works now opens
on the secret cast name and the timing being drawn by the game itself.
The ARCHITECTURE build status gains the diagnostics report.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 7201c7af82381a4b9febd1d382a3beb12afc1a9f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 02:28:28 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). 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 f4a3b03b637960e998ecf1942b53dccb911841ce
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 27 00:15:53 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 08747c481c8663c033f93b89d904ef452c9fc072
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 23:03:28 2026 +0530
PFE-ATS-SDR: Correct stale comment citations (owner-approved sync-docs follow-up)
Comment-only: the vendored LibKa0s v1.62.0 carries Bus minor 2 and Slash
minor 16, so the citations now name those versions' API documents.
- core/Bus.lua:35: docs/api/Bus/version-1-docs.md -> version-2-docs.md
- tests/test_bus.lua:88: docs/api/Bus/version-1-docs.md -> version-2-docs.md
(Known limitation 3 is unchanged at version 2)
- settings/Slash.lua:374: docs/api/Slash/version-15-docs.md -> version-16-docs.md
("The degradation stub" section exists at version 16)
- tests/test_surface_parity.lua:121: docs/api/Slash/version-15-docs.md -> version-16-docs.md
Gate: tests/run.lua 383/383 passed; lint 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 08747c481c8663c033f93b89d904ef452c9fc072
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 23:03:28 2026 +0530
PFE-ATS-SDR: Correct stale comment citations (owner-approved sync-docs follow-up)
Comment-only: the vendored LibKa0s v1.62.0 carries Bus minor 2 and Slash
minor 16, so the citations now name those versions' API documents.
- core/Bus.lua:35: docs/api/Bus/version-1-docs.md -> version-2-docs.md
- tests/test_bus.lua:88: docs/api/Bus/version-1-docs.md -> version-2-docs.md
(Known limitation 3 is unchanged at version 2)
- settings/Slash.lua:374: docs/api/Slash/version-15-docs.md -> version-16-docs.md
("The degradation stub" section exists at version 16)
- tests/test_surface_parity.lua:121: docs/api/Slash/version-15-docs.md -> version-16-docs.md
Gate: tests/run.lua 383/383 passed; lint 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 2ce21bb658f1691a5f65404c48c08d39d452b870
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 19:44:38 2026 +0530
PFE-ATS-SD: Sync docs to the tree after the automated-tests sweep
sync-docs over the tree after the sweep's run record, the LibKa0s v1.62.0
re-vendor (kit revision 31) and the final run:
- docs/automated-tests/README.md: a bundle's ANALYSIS.md was described as
written for a release run only; automated-tests-§5 makes it required at
release and recommended otherwise, and 11 of the 12 bundles carry one
(both sweep bundles included). The line now says so.
Checked and already accurate: CLAUDE.md provenance (v1.62.0), README Tests
badge (383/383), docs/test-cases.md (regenerated inventory diffs empty),
the Documentation map against docs/ (every file has a row, every row
resolves), the Tier 2 counts (18 COMMANDS, 15 Compat shims, 4 messages),
DEPENDENCIES.md tool rows and their kit citations (framework.lua:123/127,
loader.lua setfenv, the four git ls-files gates), docs/testing.md.
Stale comment citations (Bus version-1 docs vs vendored Bus minor 2; Slash
version-15 docs vs vendored Slash minor 16) are reported for owner
confirmation, not edited.
Gate: 383 passed, 0 failed, 0 skipped; lint 0 warnings / 0 errors in 75 files.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit bf7aa05cbcb62a4ae4945c2e2420003483d0a432
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 19:32:53 2026 +0530
PFE-ATS-99: Final automated-tests sweep run (20260926-193107)
Verdict green at 09cc55e (clean). lint 0/0 over 75 files; tests 383
passed / 0 skipped / 0 failed; perf 9 scenarios; complexity 9976 NLOC,
1318 functions, avg NLOC 6.3, avg CCN 2.1, max CCN 14, 0 warnings, no
file in the 1000-1500 band or over the 1500 cap.
Against the 2026-09-26 sweep run (20260926-160553, 8250bd2): nothing
moved. The only change between the two is the LibKa0s v1.61.0 -> v1.62.0
re-vendor (kit revision 31), which lives in libs/ and tests/_kit/, both
outside lint and complexity scope; the test-case inventory is identical,
and perf api/iter and bytes/iter are identical with ms/iter within noise.
The watch list is empty in both tables, so no Disposition cell needed a
refresh (ATS-23).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 09cc55e6c6017742f3b7a920c8ef68980a25c19d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 18:42:55 2026 +0530
PFE-ATS-RV: Re-vendor LibKa0s v1.62.0 (kit revision 31)
LibKa0s payload from the local v1.62.0 tag (5dc9f5d): 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 moves from kit revision 27 to 31 with the new inventory.lua, prose_coverage.lua and prose_selftests.lua; revisions 30 and 31 carry the runner fixes for ATS-20 (an empty watch-list table says None.) and ATS-21 (generated files leave the band table).
CLAUDE.md provenance and docs/ARCHITECTURE.md's two version-now lines roll to v1.62.0. No stub or suite-inventory change is owed: the new files add no Options member, and tests/run.lua derives the library load list from LibKa0s.xml. docs/test-cases.md regenerated byte-identical (383 cases before and after). Bundle in docs/revendor/2026-09-26-v1.62.0/; no adoption in this item.
Gate: 383 passed, 0 failed, 0 skipped; luacheck 0/0 in 75 files; lizard 0 over CCN 15.
Sweep ids: 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 c9b8f5c20d94a85a136a4271fe928d02942d8756
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 16:19:33 2026 +0530
PFE-ATS-00: Record the 2026-09-26 automated-tests sweep run (20260926-160553)
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 cb0a2fe06642d8717f245fab4387a19338259c6b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 14:44:01 2026 +0530
NR-PF-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 and docs/ARCHITECTURE.md's two version-now lines roll with it. The stub's no-op list gains NavRail for the Options surface-parity case.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit cb0a2fe06642d8717f245fab4387a19338259c6b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 14:44:01 2026 +0530
NR-PF-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 and docs/ARCHITECTURE.md's two version-now lines roll with it. The stub's no-op list gains NavRail for the Options surface-parity case.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 2cd2e4c13538eea7de5dd648ce6d75a690bd936f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 09:11:10 2026 +0530
DR-PF-07: Standards refresh to v2.68.0, sync-docs, AUD-01 passes (no edits)
What: the M4 close-out of the diagnostics rollout for PartyFrameEnhanced:
revendor-standards against WowAddonStandards v2.68.0 (2026-09-26, master
2854053), a sync-docs pass over the rollout's changes, and the AUD-01
check run by hand. Nothing needed changing, so this commit is empty and
exists to record the result (git is the plan's only state).
revendor-standards (no edits needed):
- Three-place reference intact: PartyFrameEnhanced.toc:12 X-Standard
URL, the bare README badge (README.md:6, no link wrapper, no %20),
CLAUDE.md "Standards compliance (read first)" with the stop-and-flag
directive and both classifications. None carries a version stamp.
- Retired notation: 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 -> 18 hits, every
one a citation of the addon's own design spec ("design spec §6.4",
docs/superpowers/specs/...), not of the standard. Not drift.
- filename-§N range check against each section file's own "### N."
headings: none unknown, malformed or out of range (CLAUDE.md:19's
"filename-§N" is the literal scheme name).
- No doc-set counts without members, no "drop-in", no retired
complexity.md / file-index.md / conventions.md / agent-context.md.
docs/ carries the trio, the verification-and-record docs, all six
Tier 1 docs, and Tier 2 docs under their canonical names.
- 3d: the standard carries no quirks-catalogue section; skipped.
- 3f: testing.md and automated-tests/README.md already name both
checkpoints (run/commit and tag); CLAUDE.md's gate line names the
commit. The RESULTS.md lead-in is runner-generated and not swept.
- 3g: .gitattributes present, CRLF pin for a client-bound repo, *.sh
carve-out and binary markings present; worktree stragglers 0 (the
line-endings-§7 check).
sync-docs (verified, nothing drifted; DR-PF-03..05 already carried it):
- docs/test-cases.md identical to a fresh `lua tests/run.lua --list`;
README badge 383/383 matches.
- 18 verbs in NS.COMMANDS = "eighteen" (ARCHITECTURE.md:139,
smoke-tests.md:49) and the slash-dispatch.md trigger row; the
thirteen reserved verbs match lib.LIVE_VERBS (Slash 16), plus status
and profile in LIVE_WHILE_DISABLED as documented.
- "Thirty-nine files" (ARCHITECTURE.md:57) = the TOC's authored files,
modules/Diagnostics.lua included; module-map.md lists it (29).
- Compat shim count 15 (14 functions + IsSecret), .luacheckrc stanza
counts, the kit's four wired suites, the Documentation map both ways,
CLAUDE.md provenance v1.60.0, DEPENDENCIES.md: all unchanged and true.
- README untouched, so no de-AI pass was due.
AUD-01, by hand:
1. grep '"diagnostics"' settings/*.lua core/*.lua: one COMMANDS row
(settings/Slash.lua:56); runDebug tests the word first
(settings/Slash.lua:242), as does the stub's DebugVerb
(core/DebugLogSetup.lua:67). The :97 hit is the live-verb list.
PASS
2. grep -rniE '"(diag|dump|dx)"' settings core modules: empty. PASS
3. liveVerbs is the hand-written LIVE_WHILE_DISABLED
(settings/Slash.lua:95-99, passed at :464): a superset of
SlashLib.LIVE_VERBS that includes diagnostics, so not the finding
("a hand-written list that omits diagnostics"); noted.
tests/test_disabled.lua:247 dispatches both forms while disabled.
PASS
4. Both forms reach NS.DebugLog:RunDiagnostics (settings/Slash.lua:57,
:243); no :Clear in modules/Diagnostics.lua. PASS
5. The stub's RunDiagnostics prints the library-absent line
(core/DebugLogSetup.lua:56-61), tested at
tests/test_diagnostics.lua:299. PASS
6. README ## Reporting a bug (README.md:110) sits between
## Troubleshooting and ## Issues and feature requests, the three
steps and the note verbatim for /pfe, no destination, no link. PASS
7. No host-written buffer or markers; the pcalls in
modules/Diagnostics.lua guard single client reads, not sections.
PASS
Result: AUD-01 passes (vendor v1.60.0, so no #47/#90).
Gate: lua tests/run.lua 383 passed, 0 failed; luacheck 0 warnings /
0 errors in 75 files; lizard -C 15 -w clean (libs, tests/_kit
excluded); largest authored Lua file 578 lines.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 2cd2e4c13538eea7de5dd648ce6d75a690bd936f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 09:11:10 2026 +0530
DR-PF-07: Standards refresh to v2.68.0, sync-docs, AUD-01 passes (no edits)
What: the M4 close-out of the diagnostics rollout for PartyFrameEnhanced:
revendor-standards against WowAddonStandards v2.68.0 (2026-09-26, master
2854053), a sync-docs pass over the rollout's changes, and the AUD-01
check run by hand. Nothing needed changing, so this commit is empty and
exists to record the result (git is the plan's only state).
revendor-standards (no edits needed):
- Three-place reference intact: PartyFrameEnhanced.toc:12 X-Standard
URL, the bare README badge (README.md:6, no link wrapper, no %20),
CLAUDE.md "Standards compliance (read first)" with the stop-and-flag
directive and both classifications. None carries a version stamp.
- Retired notation: 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 -> 18 hits, every
one a citation of the addon's own design spec ("design spec §6.4",
docs/superpowers/specs/...), not of the standard. Not drift.
- filename-§N range check against each section file's own "### N."
headings: none unknown, malformed or out of range (CLAUDE.md:19's
"filename-§N" is the literal scheme name).
- No doc-set counts without members, no "drop-in", no retired
complexity.md / file-index.md / conventions.md / agent-context.md.
docs/ carries the trio, the verification-and-record docs, all six
Tier 1 docs, and Tier 2 docs under their canonical names.
- 3d: the standard carries no quirks-catalogue section; skipped.
- 3f: testing.md and automated-tests/README.md already name both
checkpoints (run/commit and tag); CLAUDE.md's gate line names the
commit. The RESULTS.md lead-in is runner-generated and not swept.
- 3g: .gitattributes present, CRLF pin for a client-bound repo, *.sh
carve-out and binary markings present; worktree stragglers 0 (the
line-endings-§7 check).
sync-docs (verified, nothing drifted; DR-PF-03..05 already carried it):
- docs/test-cases.md identical to a fresh `lua tests/run.lua --list`;
README badge 383/383 matches.
- 18 verbs in NS.COMMANDS = "eighteen" (ARCHITECTURE.md:139,
smoke-tests.md:49) and the slash-dispatch.md trigger row; the
thirteen reserved verbs match lib.LIVE_VERBS (Slash 16), plus status
and profile in LIVE_WHILE_DISABLED as documented.
- "Thirty-nine files" (ARCHITECTURE.md:57) = the TOC's authored files,
modules/Diagnostics.lua included; module-map.md lists it (29).
- Compat shim count 15 (14 functions + IsSecret), .luacheckrc stanza
counts, the kit's four wired suites, the Documentation map both ways,
CLAUDE.md provenance v1.60.0, DEPENDENCIES.md: all unchanged and true.
- README untouched, so no de-AI pass was due.
AUD-01, by hand:
1. grep '"diagnostics"' settings/*.lua core/*.lua: one COMMANDS row
(settings/Slash.lua:56); runDebug tests the word first
(settings/Slash.lua:242), as does the stub's DebugVerb
(core/DebugLogSetup.lua:67). The :97 hit is the live-verb list.
PASS
2. grep -rniE '"(diag|dump|dx)"' settings core modules: empty. PASS
3. liveVerbs is the hand-written LIVE_WHILE_DISABLED
(settings/Slash.lua:95-99, passed at :464): a superset of
SlashLib.LIVE_VERBS that includes diagnostics, so not the finding
("a hand-written list that omits diagnostics"); noted.
tests/test_disabled.lua:247 dispatches both forms while disabled.
PASS
4. Both forms reach NS.DebugLog:RunDiagnostics (settings/Slash.lua:57,
:243); no :Clear in modules/Diagnostics.lua. PASS
5. The stub's RunDiagnostics prints the library-absent line
(core/DebugLogSetup.lua:56-61), tested at
tests/test_diagnostics.lua:299. PASS
6. README ## Reporting a bug (README.md:110) sits between
## Troubleshooting and ## Issues and feature requests, the three
steps and the note verbatim for /pfe, no destination, no link. PASS
7. No host-written buffer or markers; the pcalls in
modules/Diagnostics.lua guard single client reads, not sections.
PASS
Result: AUD-01 passes (vendor v1.60.0, so no #47/#90).
Gate: lua tests/run.lua 383 passed, 0 failed; luacheck 0 warnings /
0 errors in 75 files; lizard -C 15 -w clean (libs, tests/_kit
excluded); largest authored Lua file 578 lines.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit ed412494dfaee808124a908d616073d48be0c7b5
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 09:05:25 2026 +0530
DR-PF-05R: docs/debug.md lists the Perf tag and every ungated line
Independent review of DR-PF-05. The "Tags in use" table said it held
every tag, but it left out `Perf`: core/PerfSetup.lua's `log` writes a
perf capture's lines through NS.DebugLog:Add, ungated. The page's opening
also said only a blocked or forbidden action lands with logging off,
while a failed migration step (core/Database.lua, NS.DebugLog:Add
"Migrate") and a perf capture land too.
- The tag table gains a `Perf` row, and the `Migrate` row names the
ungated failure line.
- The console bullet names all three kinds of ungated line.
Documentation only. Gate: lua tests/run.lua 383 passed, 0 failed,
0 skipped; luacheck 0 warnings / 0 errors in 75 files; lizard -C 15 -w
clean (libs and tests/_kit excluded); largest authored Lua file 578
lines. docs/debug.md keeps CRLF.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 25b41a50ea85db0bbeeffcd624602f07d6c2bf36
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 09:03:00 2026 +0530
DR-PF-05: docs/debug.md documents the diagnostics report; the doc set catches up
debug-logging-§14 "Documented" (standard v2.68.0, STD-20). The report
shipped in DR-PF-03 and the README section in DR-PF-04; this commit adds
the page a maintainer reads a pasted report with, and corrects the count
and wiring claims the rollout left behind.
- docs/debug.md (new): the console as this addon configures it
(session-only flag, the library's 3000-line buffer, the [Init]
summary, every tag in use), then the report: both forms and no alias
(`/pfe diag` is unknown, `/pfe debug diag` toggles the window), live
while disabled, append and never clear, ungated with the flag
untouched, the reveal and the one localized chat line, the DX-PF
sections in report order with each one's tag and lines, the caps
(DIAG_MAX_LINES 1200 clamped to MAX_BUFFER - 100, 40 per list, the
200-character wrap, the truncated line), what it never does (no
writes, no protected API, no cast, fade alpha or compound UnitIsUnit
read, no GetPoint on a foreign frame, no UnitExists, nothing redacted)
and the library-absent stub line.
- docs/ARCHITECTURE.md: seventeen -> eighteen verbs, thirteen reserved
with `diagnostics`; the live-set note no longer says the verb is
unregistered; the revendor line no longer says "not yet wired";
Tier-2 rows: slash-dispatch.md 17 -> 18 commands, debug.md flips from
Not applicable to Present (documentation-§3); common-tasks row.
- docs/slash-dispatch.md: a `diagnostics` row, `debug diagnostics` in
the debug row, `diagnostics` among the verbs live while disabled, and
the degraded line for both forms.
- docs/module-map.md: modules/Diagnostics.lua as row 29 (conventional),
rows 29-38 -> 30-39; the DebugLogSetup and Slash rows name their part
of the report.
- docs/smoke-tests.md: step 4 lists eighteen verbs; section E gains
23b-23f: append and ungated, Copy and the long alias, in combat and
while disabled, no short name, and the buffer cap at 3000 (S7).
- docs/common-tasks.md: "Add a section to the diagnostics report".
- core/DebugLogSetup.lua:4: the header comment no longer states a
buffer size (the library's MAX_BUFFER), and names the report's brand,
chat line and sections hook. Comment only.
Documentation only; no test changed, so test-cases.md and the README
badge stand at 383. Every edited file keeps CRLF.
Gate: lua tests/run.lua 383 passed, 0 failed, 0 skipped; luacheck 0
warnings / 0 errors in 75 files; lizard -C 15 -w clean (libs and
tests/_kit excluded); largest authored Lua file 578 lines.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit ca671cf5fa12a55b3405b145bacb3180c973fd72
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 08:55:39 2026 +0530
DR-PF-04: README gains ## Reporting a bug; the Troubleshooting row points at it
documentation-§1 item 9 (STD-17): the section sits between Troubleshooting and
Issues and feature requests, verbatim from the standard with /pfe. Step 3 reads
"include it with your bug report" and the section carries no GitHub link.
STD-18: the Troubleshooting row that told players to copy the log into an
issue now points at the section instead.
Verified: the section diffs clean against the STD-17 text with the slash
substituted. Gate: lua tests/run.lua 383 passed, 0 failed; luacheck 0/0;
lizard -C 15 -w clean. No test changed, so the badge and test-cases.md stay.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 0dea46fc043a7e81c0e1bc5e1f69df67afd51a93
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 08:53:36 2026 +0530
DR-PF-03R: Pin the flush-listener and stand-in seams the report reads
The independent review of DR-PF-03 checked each new seam by breaking it in
a scratch copy. Two could be broken with no test going red:
- NS.PendingRegenArmed() made to return false always: only the enabled
case (armed=false) was asserted, so the report could hide the one
listener a stood-down addon keeps (slash-commands-§7).
- StandIn.IsStandIn(f) made to return false always: nothing asserted the
"(stand-in)" marker, so a solo preview's party1 row could read like a
real party frame.
Two cases in tests/test_diagnostics.lua cover them: stood down with a write
queued in combat, the report reads "flush listener armed=true" and the
queued key, and PLAYER_REGEN_ENABLED then flushes it and releases the
listener. Unlocked solo, party1's frame line carries "(stand-in)" and
party2's does not. Each goes red under its mutation and green without it.
The runDebug leading-space tolerance was also checked. Breaking it fails
nothing, because the dispatcher already trims `rest`, so it cannot be
reached from a slash line and no case was added for it.
Docs: test-cases.md regenerated (CRLF kept), README badge 381 -> 383.
Gate: lua tests/run.lua 383 passed, 0 failed, 0 skipped; luacheck 0/0
in 75 files; lizard -C 15 clean outside libs and tests/_kit; the largest
authored file is 578 lines.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 22ee02271dc0149dd690cdc930abccd718579e8d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 08:48:36 2026 +0530
DR-PF-03: The diagnostics report on the LibKa0s helper (DX-PF)
`/pfe diagnostics` and `/pfe debug diagnostics` write the report
(debug-logging-§14). 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, TOC after Preview, conventional): the
DX-PF sections in order: identity (schema stored/code, profile, latch,
holds, preview/unlock/combat/party flags, perf), non-default settings
with the always rows (enabled, locked, visibility, general.provider,
general.includePlayer), party (class tokens only, no UnitExists, which
.luacheckrc bans), frames (provider setting vs active, FrameFor by
NAME, stand-in marker, resolve state, EllesmereUI), free-placement
stored and applied anchors, per feature per unit element fields,
RangeFade mode/hooked/unit map, the secure-write queue keys, flush
listener and blocked-action count, and rejected events, bus arm and
degraded arms. Stood down, frames and fade say so; stored settings
and elements still print. It reads state only: no setting, secure
write, registration, timer, show/hide or GetPoint on a foreign frame.
- core/DebugLogSetup.lua: brandName "Ka0s Party Frame Enhanced", the
run-time diagnostics hook, and the chat line through NS.L.
- Three read-only seams the sections need: NS.PendingRegenArmed(),
Providers.ResolveState() (a fresh table), StandIn.IsStandIn(f)
(never builds the stand-in).
- settings/Slash.lua: the `diagnostics` COMMANDS row, and runDebug
tests `diagnostics` first (any case, leading space tolerated); every
other word, `diag` included, still toggles the window.
- locales/enUS.lua: the row's help text and the chat line.
Tests (STD-19): Kit.diagnostics wired in tests/run.lua, so the kit's
shared contract runs against this dispatcher (7 cases: both forms, any
case, markers, append, ungated, while disabled, no other name) instead
of its declared skip. New tests/test_diagnostics.lua (16 cases): section
order, always rows, element and secure fields, placement, queue keys and
blocked count, frames and fade, stood-down wording, one line per raising
section, a secret mock, the cap, acts-on-nothing, the never-call source
scan, the one localized chat line, and the library-absent line for both
forms. Plus a test_disabled case (both forms while disabled), a
loadorder pin, and `diagnostics` in the reserved-verb list.
Verification: grep -rniE '"(diag|dump|dx)"' settings core modules finds
nothing. Docs: test-cases.md regenerated, README badge 357 -> 381,
ARCHITECTURE thirty-eight -> thirty-nine files, testing.md's contract
note. The module-map row, verb count and debug docs are DR-PF-05.
Gate: lua tests/run.lua 381 passed, 0 failed, 0 skipped; luacheck 0/0
in 75 files; lizard -C 15 clean outside libs and tests/_kit; no file
over 1500 lines added.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit aa986e8a6237298e1df3eed8a3185d8901026975
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 04:12:33 2026 +0530
DR-PF-02: Read-only seams for the diagnostics report
The report (DR-PF-03) needs state that is file-local today. Four
read-only accessors, each handing out a copy or a number:
- NS.PendingSecureKeys(): the deferred secure-write queue's keys in
first-queued order, a copy of pendingOrder, so a reader can never
reorder or drain the live queue.
- NS.BlockedActionCount(): a new session counter, bumped in
OnActionBlocked for ADDON_ACTION_BLOCKED and ADDON_ACTION_FORBIDDEN
blamed on this addon only (the log line is unchanged).
- RangeFade.UnitMap(): the unit -> party frame map the alpha hooks read,
copied out of unitOf and keyed by unit.
- RangeFade.HookedCount(): how many party frames carry the post-hooks.
RangeFade.Mode() already existed and is the third RangeFade read.
No surface-parity change: none of these sit on a degradation stub
(core/CoreSetup.lua publishes none of them, and the modules load live in
the library-absent arm).
Tests first, red on the missing members: two lifecycle cases (key order,
dedup and copy; the counter counts ours on both events and not another
addon's) and one rangefade case (map contents and copy, hook count delta).
docs/test-cases.md regenerated, README badge 354 -> 357.
Gate: lua tests/run.lua 357 passed, 0 failed, 1 skipped (358; the skip is
the diagnostics contract, wired in DR-PF-03); luacheck 0/0 in 73 files;
lizard -C 15 clean outside libs and tests/_kit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 94aab155dbd46c79ad19aac37e13fca55f95cb50
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 03:56:01 2026 +0530
PF-DOCS: Count test_diagnostics_contract among the kit's wired suites
testing.md said three suites arrive with the vendored kit; DR-PF-01 wired a
fourth, test_diagnostics_contract, as one declared skip until the
debug-logging-§14 report lands and Kit.diagnostics is wired.
Gate: lua tests/run.lua 354 passed, 0 failed, 1 skipped (355); luacheck 0/0
in 73 files; libs/LibKa0s matches the v1.60.0 tag byte for byte.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 94aab155dbd46c79ad19aac37e13fca55f95cb50
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 03:56:01 2026 +0530
PF-DOCS: Count test_diagnostics_contract among the kit's wired suites
testing.md said three suites arrive with the vendored kit; DR-PF-01 wired a
fourth, test_diagnostics_contract, as one declared skip until the
debug-logging-§14 report lands and Kit.diagnostics is wired.
Gate: lua tests/run.lua 354 passed, 0 failed, 1 skipped (355); luacheck 0/0
in 73 files; libs/LibKa0s matches the v1.60.0 tag byte for byte.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 1843b062afbd535a199de73634d792f616b2f6c8
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 26 03:52:28 2026 +0530
DR-PF-01: Re-vendor LibKa0s v1.60.0 and stub RunDiagnostics
Both payloads copied whole from the v1.60.0 tag (DebugLog 14 with the new
DebugLogDiagnostics 1, Slash 16, WidgetsDragHandle 3, test kit 27), with the
CLAUDE.md provenance line moved in the same commit. The debug console now
keeps 3000 lines.
The copy needs three host edits to stay green:
- The library-absent DebugLog stub gains RunDiagnostics (the collection's
library-absent line naming /pfe diagnostics, nothing written, returns 0),
BuildDiagnostics and DebugVerb, so the surface parity case holds. A new
case pins the stub's behavior on a real degraded load.
- LIVE_WHILE_DISABLED gains diagnostics, since this addon passes a literal
liveVerbs and Slash 16's default does not reach it.
- tests/run.lua declares the kit's test_diagnostics_contract, one declared
skip until the report lands in DR-PF-03.
Docs: the revendor bundle (docs/revendor/2026-09-26-v1.60.0/), the
regenerated test-cases.md, the Tests badge, and the vendored version and
live-set sentences in ARCHITECTURE.md and slash-dispatch.md.
Gate: lua tests/run.lua 354 passed, 0 failed, 1 skipped (355); luacheck 0/0
in 73 files; lizard no function over CCN 15.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit d0d2d5f9ecfdce2475617f2272008237cf52d517
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Sep 25 15:04:40 2026 +0530
PF-DOCS: Sync the docs to the v1.58.0 re-vendor and the M5/M6 launcher
What: content drift left after the M5 and M6 launcher work.
- ARCHITECTURE.md: the substrate and build-status paragraphs named
LibKa0s v1.56.0; the tree vendors v1.58.0. Build status now lists the
launcher's tooltip, left click and options menu, and links the v1.57.0
and v1.58.0 revendor bundles.
- testing.md: .luacheckrc has eleven per-file stanzas, not ten
(tests/mock_menu.lua joined with 212/self + 432/self), so the tests/
stanza is the twelfth. The harness paragraph now names
tests/launcher_env.lua and tests/mock_menu.lua.
- schema.md: global.minimap.hide is no longer written from a right-click
menu. Right-click is the Enabled / Locked options menu; the Minimap
button row writes hide through NS.Launcher:SetShown.
- smoke-tests.md step 57: dropped the "hide it from LibDBIcon's own
right-click menu" route, which Launcher minor 4 replaced.
Why: sync-docs before merging the remediation branch.
Gates: luacheck 0/0 in 73 files; harness 353 passed, 0 failed;
test-cases.md matches --list; vendored payloads match ../LibKa0s.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit d0d2d5f9ecfdce2475617f2272008237cf52d517
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Sep 25 15:04:40 2026 +0530
PF-DOCS: Sync the docs to the v1.58.0 re-vendor and the M5/M6 launcher
What: content drift left after the M5 and M6 launcher work.
- ARCHITECTURE.md: the substrate and build-status paragraphs named
LibKa0s v1.56.0; the tree vendors v1.58.0. Build status now lists the
launcher's tooltip, left click and options menu, and links the v1.57.0
and v1.58.0 revendor bundles.
- testing.md: .luacheckrc has eleven per-file stanzas, not ten
(tests/mock_menu.lua joined with 212/self + 432/self), so the tests/
stanza is the twelfth. The harness paragraph now names
tests/launcher_env.lua and tests/mock_menu.lua.
- schema.md: global.minimap.hide is no longer written from a right-click
menu. Right-click is the Enabled / Locked options menu; the Minimap
button row writes hide through NS.Launcher:SetShown.
- smoke-tests.md step 57: dropped the "hide it from LibDBIcon's own
right-click menu" route, which Launcher minor 4 replaced.
Why: sync-docs before merging the remediation branch.
Gates: luacheck 0/0 in 73 files; harness 353 passed, 0 failed;
test-cases.md matches --list; vendored payloads match ../LibKa0s.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0137w2iyvwbPYwaYca4pi2Bz
commit 8263238300bed06a23d218fd8ac61384b2e84299
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Sep 25 00:08:49 2026 +0530
M6-PF: Document the launcher's left-click settings and right-click menu
What: the docs now describe Launcher minor 4 as this addon uses it.
- README: the minimap button paragraph (left-click opens settings;
right-click opens a menu of Enabled and Locked, with Locked grayed
while off). The Tests badge is now 353/353.
- ARCHITECTURE.md: the Launcher table's Left click, Right click and
Tooltip rows. The rung wording is gone from the closing paragraph.
- settings-panel.md: the Minimap button row gets the new hints and a
clicks clause.
- module-map.md: the LauncherSetup row.
- smoke-tests.md: step 10d (disabled: the panel opens and Locked is
grayed), step 53 (the fixed hints), step 54 (left-click opens
settings), step 55 (the options menu, each entry the same as its
slash verb, grayed while disabled), and step 56 (the broker row).
- test-cases.md: regenerated with `lua tests/run.lua --list` (353).
Why: M6 / launcher-§2 (standard v2.67.0). The previous commit changed
the behavior these docs describe.
Departures: none.
Gates: luacheck 0/0 in 73 files; harness 353 passed, 0 failed; no
function above CCN 15.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 5efd8b1d1891e31bdac3ea254c70c9d019accde2
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Sep 25 00:08:36 2026 +0530
M6-PF: Re-vendor LibKa0s v1.58.0 and pass the launcher's menu toggles
What: copy LibKa0s/ -> libs/LibKa0s/ and testkit/ -> tests/_kit/ whole
from the local LibKa0s tag v1.58.0 (git archive; rm -rf then copy) and
roll the CLAUDE.md provenance line v1.57.0 -> v1.58.0. diff -r against
the tag is empty for both payloads. One file moves: Launcher.lua, minor
3 -> 4. The kit stays at revision 26. Bundle written to
docs/revendor/2026-09-25-v1.58.0/ (01_DELTA.md, 05_SUMMARY.md), in the
same shape as M5's v1.57.0 bundle.
core/LauncherSetup.lua passes the pairs this addon has, each wired to
its slash verb's own handler: setEnabled -> NS.SetEnabled (newly
published from settings/Slash.lua as runEnabled, the /pfe enable|disable
handler) beside isEnabled, and toggleLock -> NS.ToggleLock (the /pfe
lock|unlock and Lock frame seam) beside isLocked. onClick,
leftClickLabel and disabledLine are removed, along with the two enUS
keys only the label read. isLocked, isEnabled and version are kept from
M5. The menu is Enabled and Locked, which matches ADDONS.md's row
(WS-11). There is no test mode (unlocking is the preview,
options-ui-§15) and no primary window.
Why: M6 / launcher-§2 (standard v2.67.0). The owner ruled that
left-click opens settings, and that right-click opens a context menu of
the addon's own toggles, wired through the addon's handlers.
Tests (written first, red before the change): tests/mock_menu.lua is a
verbatim copy of LibKa0s v1.58.0's MenuUtil fake, because the kit ships
none. tests/launcher_env.lua installs it as mocks.__menu. The tests
cover these cases:
- left-click opens the panel, enabled and disabled
- the menu's title, and exactly Enabled and Locked
- states read at open
- Locked routes to NS.ToggleLock and writes locked through the one seam
/pfe lock uses
- Enabled routes to NS.SetEnabled with the target state and prints the
echo /pfe disable prints
- Locked is grayed while disabled, even a forced click calls nothing,
and Enabled stays live
- with no MenuUtil, the right click falls back to the panel
- the descriptor carries no retired field
- the tooltip's fixed hints
test_disabled's launcher case is re-pinned the same way.
Departures:
- One commit carries both the payload and the adoption. The payload
alone turns 7 cases red (they pinned rung b, the refusal and minor 3's
hints), and the green gate holds for every commit.
- .luacheckrc narrows 212/432 on self for the verbatim mock, so it
stays a clean re-copy.
Gates: luacheck 0/0 in 73 files; harness 353 passed, 0 failed; no
function above CCN 15; no authored .lua file above 1500 lines.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 975574a0e1b802a5b500c274292ee2006a080b08
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 23:12:00 2026 +0530
M5-PF: Answer the launcher's status tooltip from the addon's own states
What: core/LauncherSetup.lua passes the Launcher minor 3 fields for the
states this addon has. isEnabled (the Enable row) and disabledLine
(NS.DisabledLine) give a truthful Enabled line and the disabled hint.
isLocked reads the `locked` row. version is NS.Version(), the TOC's
## Version. leftClickLabel names the next lock state ("Unlock frame" /
"Lock frame", rung b per ADDONS.md) through NS.L, with two new enUS keys.
No isTestMode, because the addon has no test mode (unlocking is its
preview, options-ui-§15). No onTooltipShow, because the addon never
passed one and has nothing of its own to add.
Why: M5 / launcher-§1 (standard v2.66.0). The owner ruled that the
button always shows its status, disabled included, in the
library-drawn shape.
Tests (written first, 6 red before the change): tests/launcher_env.lua
captures the descriptor; tests/test_launcher.lua pins its fields and
their sources, and hovers the object through a mock tooltip to read
every line while enabled+locked, unlocked, and disabled (Enabled: No,
"Left-click: disabled — /pfe enable", one refusal line on click, no
chat on hover, re-read after re-enable), plus the locale route.
Docs: ARCHITECTURE.md launcher table (Tooltip row; the left-click gate
is now the library's), settings-panel.md Minimap button row,
module-map.md, README, smoke step 53, and a ToggleLock comment in
settings/Slash.lua. test-cases.md regenerated and the badge at 348/348.
Departures: isEnabled/disabledLine were not named in the task's field
list, but without them the library draws "Enabled: Yes" forever and no
disabled hint, which the owner's ruling forbids. The library's gate now
refuses a disabled click before NS.ToggleLock. Its own gate is kept for
any other caller, so the player still sees one line.
Gates: luacheck 0/0 in 72 files; harness 348 passed, 0 failed; no
function above CCN 15; no authored .lua file above 1500 lines.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit cb959cce60d1acccb75d5d83242ee3fd3f2275e4
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 23:10:21 2026 +0530
M5-PF: Re-vendor LibKa0s v1.57.0 and record its delta bundle
What: copy LibKa0s/ -> libs/LibKa0s/ and testkit/ -> tests/_kit/ whole
from the local LibKa0s tag v1.57.0 (git archive; rm -rf then copy), and
roll the CLAUDE.md provenance line v1.56.0 -> v1.57.0 in the same commit.
diff -r against the tag is empty for both payloads. One file moves:
Launcher.lua, minor 2 -> 3 (the library always draws the status
tooltip). The kit stays at revision 26, byte-identical.
Why: M5 (the owner's always-on launcher tooltip ruling, launcher-§1 as
of WowAddonStandards v2.66.0) needs Launcher minor 3.
Writes docs/revendor/2026-09-24-v1.57.0/ (01_DELTA.md, 05_SUMMARY.md)
shaped as RV-PF's v1.56.0 bundle. No contract blockers. The owed
descriptor adoption is the next M5-PF commit.
Gates: luacheck 0/0 in 72 files; harness 342 passed, 0 failed (same as
the v1.56.0 baseline); no function above CCN 15; no authored .lua file
above 1500 lines.
Departures: none.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit a8647506cae346a1f56e7bddd558e7b32409967a
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 13:25:51 2026 +0530
PF-25: Refresh the standards reference against WowAddonStandards v2.65.0
/wow-addon:revendor-standards run against the merged-and-pushed standard
(STANDARDS.md "v2.65.0, 2026-09-23"; gate `gh api .../STANDARDS.md | grep
v2.65.0` hit). Section files read from origin/master of the sibling right
after `git fetch` (byte-identical to the GitHub copy; raw curl was stalling).
Applied (comment-only, pre-authorised by the item text):
- core/DebugLogSetup.lua:4 — "500-line buffer" -> "1500-line buffer", the
number debug-logging-§1 states since WS-07 and LibKa0s DebugLog MAX_BUFFER.
Verified, no change needed:
- Three-place reference (documentation-§6): TOC ## X-Standard URL, bare
README ![Standard] badge (not a link, `_` escapes), CLAUDE.md "Standards
compliance (read first)" carries the canonical stop-and-flag block and the
two-way classification with the Documented-deviations register.
- 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 -> 18 hits, every one
citing the addon's own design spec ("design spec §6.x", docs/superpowers/),
none citing the standard; 3 further hits in frozen bundles left as evidence.
- filename-§N range check against every section's heading count: zero
malformed, zero out-of-range (only the canonical `filename-§N` placeholder).
- No retired doc-set counts, drop-in label, agent-context.md, complexity.md,
file-index.md or conventions.md. docs/ holds the canonical trio, the five
record docs, all six Tier 1 docs, and Tier 2 docs under canonical names.
- automated-tests-§3 gate statements in docs/testing.md and
docs/automated-tests/README.md already name both checkpoints. The
RESULTS.md lead-in is runner-generated and out of this sweep's reach.
- .gitattributes: CRLF pin (client-bound), *.sh LF carve-out, binaries
marked; worktree stragglers 0 (line-endings-§7 byte-count command).
- No quirks catalogue section in the standard: nothing to vendor.
- Bootstrap `_` wording (WS-07(2)): code already names the unused vararg
`_`; no doc restates the old rule.
No findings resolved (item carries none).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 12222513c8391c85cd8fcaee06da1f98dbb70766
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 11:06:39 2026 +0530
PF-DOCS: Record the 20260924-110428 automated-test bundle
tests/_kit/run-automated-tests.sh (kit revision 26 runner, all four
suites) over c888121, clean tree, on the remediation branch:
- lint pass, 0/0 in 72 files
- tests pass, 342/0/342 (docs/test-cases.md and the README badge agree)
- perf pass, 9 scenarios
- complexity pass, max CCN 14, 0 functions above 15, no file in either
layout-§1 band
The manifest carries the commit cell (full sha, branch, dirty=false),
and RESULTS.md was widened once with the Commit and Tree columns, the
nine earlier rows carried forward as unknown. The bundle's ANALYSIS.md
follows the AUTOMATED_TESTS.md playbook template and compares against
20260918-121606, which measured e4d7f41 63 commits back. This bundle
replaces it as the current record. Not a release run: no version bump,
no tag, and the TOC is still 1.0.1.
Findings: PartyFrameEnhanced-A-17
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit c8881214551ab595aba32739fc482f7688039b4e
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 11:04:22 2026 +0530
PF-DOCS: Sync the docs to the v1.56.0 re-vendor and the M3 changes
The sync-docs pass over README.md, CLAUDE.md, DEPENDENCIES.md and docs/
after RV-PF and PF-00..PF-24. Most of the ripple already landed with
each item; this commit fixes what was still stale:
- docs/ARCHITECTURE.md: LibKa0s v1.55.0 -> v1.56.0 in the substrate and
build-status paragraphs, and the build status now names what v1.56.0
brought (Schema minor 2 with writeThrough, Core minor 8's
SafeRegister* family, the Slash stub shape) and links the v1.56.0 and
v1.37.0..v1.54.2 revendor bundles.
- docs/testing.md: .luacheckrc has ten 212/self stanzas (PF-00 added
modules/Anchor.lua), not nine, plus the files["tests/"] globals stanza.
- docs/slash-dispatch.md: the degraded section names the one
library-absent line PF-12 introduced, the writeThrough route for
enable/disable, the plain `cmd desc` rows, and the parity pin on the
stub's refusal format.
- docs/smoke-tests.md: step 10f's combat half used the settings panel,
which refuses every write in combat; it now uses /pfe disable and
/pfe enable. New step 10h covers PF-06's fade frames and holders
through a stand-down in combat.
- DEPENDENCIES.md: the timeout bound is dated "since kit revision 23",
since the kit is now at 26.
Verified unchanged and correct: 17 verbs, 15 Compat shims, 12 wired
LibKa0s majors, 38 authored TOC files, the Event Subscriptions and
Message Bus tables against the source, the CLAUDE.md v1.56.0
provenance line, the global.minimap.shown path, the library-stack-§6
register row, docs/test-cases.md (diff against --list is empty) and the
README badge (342/342). The dotted-section sweep finds only citations
of the addon's own design spec (PartyFrameEnhanced-A-18: no action).
The automated-test bundle (PartyFrameEnhanced-A-17) follows in its own
commit, so its manifest records this clean commit.
Findings: PartyFrameEnhanced-A-18 (and A-17 with the next commit)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit b81b29141f00909d47e181b18ea624a6613f972f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:57:41 2026 +0530
PF-24: Record the v1.37.0..v1.54.2 re-vendors in one span bundle
The amended re-vendor check (AUDIT.md per WS-01, revendor-libka0s Step 3h
per WA-01) was run at the 2026-09-15 horizon that the 2026-09-23 audit
used. docs/revendor/ recorded only v1.55.0 and v1.56.0. It listed 15 tags
as vendored and unrecorded. One is v1.36.1, the scaffold's first vendoring
at 246dba6. That is the base, not a re-vendor. The other 14 are recorded
here in one consolidated span bundle, docs/revendor/2026-09-24-v1.37.0-v1.54.2/,
which holds 01_DELTA.md and 05_SUMMARY.md only.
01_DELTA.md line 1 follows the WS-01 grammar exactly and names every tag
in the span. The body states the true previous base (v1.36.1) and the
listing commands with their output. For each tag it gives the LibKa0s
commit, the repo carrier commit, the date and the diff --stat from the
previously vendored tag. It also has a per-file minor table across all 15
tags, plus the kit revision. Every carrier commit's libs/LibKa0s and
tests/_kit tree hash matches its tag. 05_SUMMARY.md gives one line per tag:
the adopting commit, or "carried by sweep, nothing adopted".
After this commit the check at the store's own horizon reports nothing
unrecorded. At the 2026-09-15 horizon it reports only v1.36.1, the base.
Frozen bundles are untouched.
Deviations from the item text:
- The span ends at v1.54.2, not v1.53.0, and the folder is
2026-09-24-v1.37.0-v1.54.2. The plan-review correction derives the tag
list from git log -- libs/LibKa0s tests/_kit, and that brings in the
kit-only re-vendor 7eea3d0 (v1.54.2). The item's verify glob
*-v1.37.0-v1.53.0 therefore matches the -v1.37.0-v1.54.2 folder instead.
- v1.42.0 is in the span, although the item's expected list leaves it
out. It was re-vendored inside the feature commit a8e3a44, and only the
payload walk finds it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit fa93e5c9157c0a008b76af8248ee233c633db7c7
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:52:26 2026 +0530
PF-23: address review — compat-layer no longer claims an exhaustive list of raw calls
The "Three raw calls stay outside it" sentence undercounted: UnitButtons calls
UnitHealth/UnitHealthMax/UnitName, TargetFrames and PetFrames call UnitName,
StandIn calls UnitClass/UnitPowerType/UnitName. Reworded as a non-exhaustive
"for example" list of the stable unit queries called directly, with how each
kind of answer is kept secret-safe (finding A-12).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit b90e4d2a4f45ea86bb27b9df1d7342465f44bd93
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:48:58 2026 +0530
PF-23: Name Preview as a bus consumer and sync six doc-drift sites
- docs/ARCHITECTURE.md Message Bus: the ConfigChanged and ProfileChanged
Consumers cells now name Preview (modules/Preview.lua registers both).
New tests/test_bus.lua case derives each message's receivers from
source (RegisterMessage(NS.MSG.<KEY> in core/ and modules/) and asserts
every receiving module appears in that message's Consumers cell; it was
red on Preview before the doc edit.
- CLAUDE.md and docs/ARCHITECTURE.md header: the resume point is
ARCHITECTURE.md plus GitHub issues; the v0.1.0 build plan is history.
- docs/module-map.md: State no longer lists a `test` field.
- docs/compat-layer.md: the blank lines splitting the shim table are gone;
'never the raw API' now names the three raw calls (CastBars
UnitCastingInfo/UnitChannelInfo, RangeFade UnitInRange, TargetFrames
UnitName) and why each is safe.
- docs/ARCHITECTURE.md launcher Right click: restated per the standard's
v2.57.0 ruling (the settings panel is setup, reachable in either state).
- defaults/Profile.lua header: drops 'the phase that builds each feature'.
- ARCHITECTURE.md documentation map keeps '15 shims' (14 function
statements plus the Compat.IsSecret assignment) and adds the counting
grep beside it (the pipe escaped as \| for the table cell).
- docs/test-cases.md regenerated, README badge 342/342.
Findings: PartyFrameEnhanced-A-10, PartyFrameEnhanced-A-12.
Deviations: the item's line cites had drifted (Right click is now at
ARCHITECTURE.md:156, '15 shims' at :361, Preview's registrations at
Preview.lua:175/:184); edited the intended sites.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 1153faf4e8870a7330127fcc11726d9e50e26e86
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:46:09 2026 +0530
PF-22: address review — reword the two comments still citing the retired deviation
CastBars.lua and TargetFrames.lua still called their per-unit
RegisterUnitEvent registrations a documented deviation from
events-frames-taint-§1, but 79cd225 retired that register row.
Both now match PetFrames.lua: "not a deviation; see Event
Subscriptions in docs/ARCHITECTURE.md". Comment-only. This also
corrects 79cd225's commit body, which said no comment was left
citing the retired row.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 79cd225ddb8ef35c0d2e92238dac7f2f88478d57
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:43:30 2026 +0530
PF-22: Retire the stale taint row, register the EllesmereUIDB read
docs/ARCHITECTURE.md ## Documented deviations: delete the
events-frames-taint-§1 row. The standard's v2.63.0 changelog item 5
ruled it is not a violation (the RegisterUnitEvent registrations sit on
the elements themselves, not on frames made for events); that one-line
rationale, citing the ruling, now closes ## Event Subscriptions in place
of "a recorded deviation, below". Add the library-stack-§6 row for the
owner's A-05 decision, option (b): keep ellesmereConfiguredSize()'s
read-only, nil-guarded EllesmereUIDB size read, because EllesmereUI's
hidden party buttons carry its raid size, with its re-check trigger.
### Files over the 1500-line cap stays under the heading.
docs/scope.md names the EllesmereUIDB size read beside "reads their
position and unit". modules/Providers.lua's comment above
ellesmereConfiguredSize() cites the register row.
Findings: PartyFrameEnhanced-A-04, PartyFrameEnhanced-A-05,
PartyFrameEnhanced-A-06.
Deviation from the item text: modules/PetFrames.lua's header comment
also called its RegisterUnitEvent use "the documented deviation in
docs/ARCHITECTURE.md"; reworded to point at Event Subscriptions so no
comment cites the retired row. The item's Providers.lua :286-291 cite
had drifted to :289-294.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 4cade67ed8828aa9c07aaf0521980146e366f820
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:39:33 2026 +0530
PF-21: Open every file on the bootstrap, header beneath; derive LOGO_PATH
Every TOC-listed authored file now opens with `local <name>, NS = ...` on
line 1 (architecture-§1) and carries its `-- <path>` self-naming header
directly beneath it (documentation-§9).
- Moved the bootstrap above the header in locales/enUS.lua,
core/MediaSetup.lua, core/EnvSetup.lua and settings/About, General,
ElementRows, CastBars, TargetFrames, PetFrames and Profiles.
- Added path headers to core/Namespace.lua, core/Constants.lua and
core/State.lua.
- core/Constants.lua line 1 is `local addonName, NS = ...`, and
C.LOGO_PATH is built from addonName (same resolved value today).
Tests (red first): test_loadorder "every TOC-listed authored file opens on
the namespace bootstrap" (line 1 is the bootstrap, one of lines 2-4 is the
path header), and test_mediasetup "LOGO_PATH is the shipped logo, derived
from the folder name" (pins the value and loads core/Constants.lua under a
different folder name). docs/test-cases.md regenerated; badge 341/341.
Findings: PartyFrameEnhanced-A-13, PartyFrameEnhanced-A-14,
PartyFrameEnhanced-A-16.
Deviation: the item listed 13 files, but core/Database.lua,
settings/Slash.lua and core/CoreSetup.lua already opened on the bootstrap
with their header on line 5, below a preamble, so the item's own test
(header on lines 2-4) was red for them too. Their header block was moved
up to sit directly beneath the bootstrap, as documentation-§9 asks.
The LOGO_PATH case lives in tests/test_mediasetup.lua (a Constants case)
rather than tests/test_optionssetup.lua.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 65317f4733c7d39b9bf1b688a356ed95001fb9f8
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:35:49 2026 +0530
PF-20: Annotate LifecycleSetup's load-bearing TOC slot and pin it
core\PerfSetup.lua hands NS.lifecycle to LibKa0s-Perf-1.0 at file load,
so core\LifecycleSetup.lua must load first; the TOC's only note there
talked about NS.Perf and sat above the wrong file. LifecycleSetup now
carries its own LOAD-BEARING line (publishes NS.lifecycle), and the
NS.Perf note moved directly above core\PerfSetup.lua.
New case in tests/test_loadorder.lua (MediaSetup case's shape): asserts
LifecycleSetup precedes PerfSetup and the TOC says why. Red before the
TOC edit (the "publishes NS.lifecycle" note was missing), green after.
docs/test-cases.md regenerated; README Tests badge 339/339.
Finding: PartyFrameEnhanced-A-07
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 49881484dce45923d0296b7ded46bbb039e4a6e9
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:32:19 2026 +0530
PF-19: Refresh perf figures and attribute settingsDrag's growth
docs/performance.md's scenario table and "Figures from" line now carry
the 2026-09-24 measurements (three identical runs of tests/perf.lua):
castStartStop 3.6 B/iter (was 16.6), settingsDrag 925.9 (was 596).
Every other figure was unchanged. No ceiling value moved.
settingsDrag's growth is attributed by measurement. tests/perf.lua ran
at every commit from 6722124 (the perf pass) to f5d11ec (PF-18), then
each move was isolated by removing the suspect lines from a scratch copy:
- 285623b: 595.9 -> 885.9. The kit mock has no RegisterForDrag or
EnableMouse, so its catch-all __index builds a no-op closure per call.
That is six closures, 288 B, all harness garbage. Without those calls
the scenario reads 597.9.
- f14b096 (LibKa0s v1.47.0): +10. 8aa8a10 (PF-11, Schema Set): +40.
f5d11ec (PF-18, perf.lua only): -10.
The structureSignature theory in the finding does not hold. Each commit
that touched modules/Element.lua after 6722124 measured the same as its
parent.
castStartStop dropped from 16.6 at a8e3a44 (the stand-down latch). The
doc says so next to issue #12. Since that commit it reads 3.6 or 5.4 at
different commits, including ones that change no cast path; a single
tree always gives the same figure.
tests/perf.lua ceiling comments now give the measured figure and drop
the claim that the drag's bytes are the signature string.
Finding: PartyFrameEnhanced-R-12.
Deviation: the item names "~896" as the current drag figure. Today's run
reads 925.9, after PF-11 (+40) and PF-18 (-10). The doc records the
measured figure.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit f5d11ec42691462827ac7ac9a094a57c23ad7c69
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:18:44 2026 +0530
PF-18: Pin zero-overhead scenario against absent instrumentation
tests/perf.lua scenario 8 compared capture-off with capture-on
(probeOff.bytesPerIter <= probeOn.bytesPerIter + 1), which would pass a
dormant bracket that allocates as much as an armed one. performance-§9
wants capture-off pinned against the path with the instrumentation
absent. The bracket cannot be compiled out, so the scenario now wraps
its only two entry points, the mock-global debugprofilestop and
NS.Perf.Note, with call counters and asserts 0 calls per iteration
while NS.Perf.on is false. The off-vs-on byte comparison is gone. The
24 B probeOverheadOff ceiling and the same-API-count assertion stay.
No wall-clock assertion. The scenario stays outside docs/test-cases.md,
and the report prints "probeOverheadOff N bracket calls/iter".
Red first: in a scratch copy with CastBars' `Perf.on and
debugprofilestop()` changed to `debugprofilestop()`, perf.lua exited 1
with "a dormant bracket made 6.0 clock/Perf.Note calls per pass".
docs/performance.md: the probeOverhead row's assertion column now
describes the new check.
Finding: PartyFrameEnhanced-R-07.
Deviations: added a liveness assertion (the counters must see > 0
calls with capture on, 9/iter today) so the zero cannot be vacuous.
Also updated the docs/performance.md row, which the item text did not
mention.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 454d4d9cf1acad66a4f607c71ab6df9081b5f716
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:16:02 2026 +0530
PF-17: Ship no screenshots, drop phantom ignores, fix screenshot names
.pkgmeta now ignores media/screenshots: the client cannot load .png and
the README links the CurseForge copies, so the three files were dead
weight in the package. The .claude and .superpowers ignores are deleted;
neither directory exists in the repo (packaging, branch c: an ignore for
a missing path is a false claim).
The screenshots are renamed from the misspelled partframeenhanced.* to
partyframeenhanced.* with git mv. Nothing in code or docs references the
local files.
Findings: PartyFrameEnhanced-R-18, PartyFrameEnhanced-A-15.
Deviation: the verify grep for 'partframe' still hits README.md:27,31,35.
Those are the forgecdn attachment URLs, whose paths CurseForge derived
from the uploaded filenames; editing them would break the images. They
stay as they are. The intent of the check, no misspelled local files,
holds.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit fda8c4d080a41343c46cfefdbaebef8e39946f21
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:13:31 2026 +0530
PF-16: Opt holders and the stand-in out of the client's layout cache
The free-placement holders (modules/Anchor.lua) and the preview stand-in
(modules/StandIn.lua) are movable named frames, so the client would record
their dragged positions in layout-local.txt and restore them over the
position the addon re-anchors them to. Both now call
SetDontSavePosition(true) right after SetMovable(true), presence-guarded,
with one comment line each and no standards clause cited.
Tests (red first, then green): test_anchor and test_standin give named
frames a recording SetDontSavePosition and assert it was called with
true; a frame whose method is absent still builds. The stand-in cases
load a fresh copy of modules/StandIn.lua under a wrapped mock view,
because the suite's own stand-in is built once and cached. docs/test-cases.md
regenerated; README badge 334 -> 338.
Finding: PartyFrameEnhanced-R-16.
Deviations: the item cited Anchor.lua :257 for holder:SetMovable(true);
it is at :261 in the current tree. The StandIn comment says the frame is
placed from the imitated frame (its actual source) rather than from a
stored or default position.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 20e0dd032454365c1154d814226691749662bd86
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:08:51 2026 +0530
PF-15: Route provider and stub strings through NS.L; drop dead keys
locales/enUS.lua: delete the dead 'Position' key and the unread
'/pfe %s does nothing while the addon is off ...' refusal key; collapse
the two near-duplicate pairs ('All settings reset to defaults[.]',
'Cannot reset settings ... failed to load[.]') to the no-period
spelling, and point settings/General.lua's global reset at the kept
keys (settings/Slash.lua already read them). Add keys for the two
Blizzard provider labels and the degraded DebugLog stub's two strings.
A literal-reader scan of enUS.lua found no other key PF-07/PF-12 left
without a reader.
modules/Providers.lua: the three labels are L[...] at definition
(local L = NS.L; locales load first). core/DebugLogSetup.lua degraded
stub: the ack is one format string, L["debug logging %s"], and the
checkbox label is L["Debug console"].
Tests (red first): test_slash asserts every provider label is an enUS
key and that `/pfe status` ends its first line with the L-routed
label; test_debuglog loads the degraded env, seeds translations of
both stub keys and asserts one ack line and the label use them.
docs/test-cases.md regenerated, badge 334/334.
Findings: PartyFrameEnhanced-R-14, PartyFrameEnhanced-A-09.
Deviations: the item's verify grep `load\."\]` over settings/*.lua
still matches settings/Slash.lua:366, the key
"%s is unavailable: the LibKa0s library did not load." That is not one
of the near-duplicate twins; it is the library-absent line PF-12 pinned
to the LibKa0s stub shape and tests/test_surface_parity.lua checks, so
it is left as is. Line cites shifted since the plan was written
(refusal key at :153, twins at :133-135, General.lua at :213/:215).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 7799b953814ddedfda6ee6a1192e6830e8e13f94
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:04:16 2026 +0530
PF-14: Drop the unused read_globals from .luacheckrc, UnitExists first
The read_globals list carried eleven names no authored Lua reads as a bare
global (GetTime, wipe, Mixin, UnitExists, UnitGUID, UnitIsUnit,
UnitIsDeadOrGhost, UnitIsConnected, C_Secrets, RegisterUnitWatch,
UnregisterUnitWatch). Whitelisting UnitExists let a raw
UnitExists(compound token) lint clean, which is the secret-value hazard
core/Compat.lua's "No UnitExists shim" note documents removing; a comment
now stands where it was. UnregisterStateDriver stays (PF-04 calls it), as
does EventRegistry.
The zero-use re-check (linting against an empty read_globals and
collecting every W113) also found EllesmereUI with no bare-global read
after PF-09/PF-10 (only comments and string labels name it), so it goes
too. _G and select are kept though lua51 std already provides them.
Finding: PartyFrameEnhanced-R-13.
Deviation: EllesmereUI removed in addition to the eleven named names, per
the item's re-grep instruction.
Gates: lint 0/0, tests 332 passed 0 failed, lizard -C 15 clean.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit ac00e34bd1ee70ec99cf69b7410601f2fa496169
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 10:01:11 2026 +0530
PF-13: Read the minimap row's CLI path in its shown sense
The Master controls Minimap button row's schema/CLI path is now
`global.minimap.shown` (launcher-§3 as amended by WS-06; spec C46). The
row's get/set closures (settings/General.lua) keep inverting onto
LibDBIcon's stored `NS.db.global.minimap.hide` and calling
NS.Launcher:SetShown; no `shown` key is ever stored (anti-pattern #81).
resetExempt / NS.IsGlobalSetting / OptionsSetup's exemptFromReset all
key off NS.MINIMAP_PATH, so they follow the rename.
Validation: the path is no longer a storage path, so defaultsRoot now
answers nil for the global row (exempt from the resolution check the way
a sessionOnly row is), and tests/test_schema.lua pins the storage default
`NS.defaults.global.minimap.hide` directly.
SavedVariables are unchanged: no migration step, NS.SCHEMA_VERSION stays
at 1. Carry-over pinned test-first: a legacy store
`minimap = { hide = true, minimapPos = 200 }` reads `get
global.minimap.shown` as false, the button stays hidden, minimapPos is
untouched, and a set writes no `shown` key to the raw SV.
tests/launcher_env.lua gained an optional seeded-SV argument for it.
Player-facing CLI change for the next Version History roll:
`/pfe set global.minimap.hide <v>` becomes
`/pfe set global.minimap.shown <not v>`; the old path now answers
"Setting not found" (no alias).
Docs: ARCHITECTURE.md Global rows + launcher Visibility cell, schema.md,
settings-panel.md, smoke-tests.md (#57 gains the CLI/SV checks).
docs/test-cases.md regenerated; README badge 328 -> 332.
Deviation: the item cites MINIMAP_PATH at settings/General.lua:51; the
constant actually lives in settings/Schema.lua (NS.MINIMAP_PATH) and
General.lua reads it, so the rename was made there.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit c47e5de5b9152cfdb8487e512451aafc5caea06b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:55:05 2026 +0530
PF-12: Give the library-absent Slash stub the prescribed LK-18 shape
settings/Slash.lua's degraded stub now takes the shape LibKa0s
docs/api/Slash/version-15-docs.md ("The degradation stub") prescribes
under slash-commands-§1/§7:
- The copied FormatRow (`cmd — desc`) is gone; the stub table carries no
FormatRow. Help, landing and profile rows render as `cmd desc` through
one local plainRow, used only when SlashLib is absent
(printProfileHelp reads `SlashLib.FormatRow or plainRow`).
- DISABLED_LINE stays the verbatim DISABLED_LINE_FORMAT bytes and is
published as Sl.__disabledLineFormat on the degraded load only.
- The schema CLI verbs' absent(verb) prints WS-02's one-sentence line,
L["%s is unavailable: the LibKa0s library did not load."] formatted
with "/pfe <verb>". The old `missing` concatenation and the
"is unavailable." locale key are removed; the new key is added.
- The false comment ("No formatter ... is copied here") is replaced by
an accurate one: minimal sanctioned OnSlash dispatch, the pinned
refusal format, plain rows, no library formatter or parser.
enable/disable/lock/unlock need no stub change (PF-11's writeThrough,
route (a)).
Tests (red first, both failed for the right reason): the stub's format
is pinned with T.assertLibraryConstant (the kit's LibStub fallback
resolves the lib-level member although the runner maps the major to the
instance); a new case checks degraded /pfe help and landing rows carry
no em-dash separator, /pfe list prints exactly the library-absent line,
and /pfe profile answers without raising both with no AceDB and with a
profile store (plain rows). The Slash parity exclusion comment is
updated. docs/test-cases.md regenerated; badge 326 -> 328.
Resolves: PartyFrameEnhanced-R-11
Deviations: the item's line cites (:322-391, :243, :64-65) predate
earlier items; the intended code was changed at its current location.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 8aa8a1024ce253defff4e454bd9f65dd658879e0
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:48:59 2026 +0530
PF-11: Adopt LibKa0s-Schema-1.0 with writeThrough {enabled, locked}
Re-applies the rolled-back Schema adoption (issue #14) on WS-02 route (a).
settings/Schema.lua is now the setup file: it resolves LibKa0s-Schema-1.0
(minor 2) or a HostSchemaStub copied from LibKa0s tests/test_schema.lua's
referenceStub ("The degradation stub", version-2-docs.md), and builds one
instance over NS.Schema with resolveRoot, announce (CONFIG by section,
skipping sessionOnly and writeThrough rows), debug/debugEnabled/format/
print forwarders, resetExempt = the global minimap path, and
writeThrough = { "enabled", "locked" }. Both the instance and the stub take
that list, so the library-less build's /pfe enable|disable|lock|unlock and
modules/Preview.lua's forceLock still write, while any other row-less path
is refused.
The host names bind onto the instance (SetByPath = inst.Set, FindSchemaRow,
ApplyDefault, Bulk.Begin/End/Run, the reset count, ValidateSchema over
inst.Validate; ResolvePath/SetPath = SchemaLib.Read/Write; GetSetting =
inst.Get with the defaults.profile fallback). byPath, the host bracket,
SetSetting and the session and global registries are deleted:
settings/General.lua stamps get/set onto the composed debug-console and
minimap rows by path. NS.IsGlobalSetting survives as the source of the
reset-count predicate, resetExempt, the validator's defaults root and the
Reset All veto. The Options descriptor keeps call-time forwarders for set
and applyDefault; its applyDefault no longer vetoes the minimap row itself,
because resetExempt does so inside the bracket both panel resets open.
The Slash descriptor's set still returns nothing (AcceptLock prints its own
line). NS.__schema and NS.__schemaLib are published for parity.
Tests: characterized first. The degraded /pfe unlock and /pfe lock writing
`locked` were green on the host seam; the degraded write to general.__nope
was red (the host seam stored it) and is green now. Re-pinned deltas: an
unknown path is refused on the live build, a table value is copied into the
store, and a refused write logs no '%s refused' line. The bracket-raise
probe now writes a shipping row (general.rangeFade). New parity cases pin
the stub instance against the live instance and the stub library against
LibKa0s-Schema-1.0 (STRINGS ignored); tests/run.lua registers the Schema
surface source. docs/test-cases.md regenerated, badge 326/326.
Docs: ARCHITECTURE (majors list, Settings Schema, writeThrough, Global
rows, Known Limitations: a library-less enable/disable/lock/unlock stores
the switch without the row's onChange), schema.md (new "The write seam"),
settings-panel.md, module-map.md, slash-dispatch.md.
Deviations: the item's `defaultsRoot = NS.defaults and NS.defaults.profile`
is not what Validate takes (it needs a function); a function returns
NS.defaults for the global minimap row, nothing for a Profiles row, and
defaults.profile otherwise. Descriptor debug/print/format are call-time
forwarders rather than the bare NS.Debug/NS.Print values, because suites
swap NS.Debug. The stub keeps every reference member (none trimmed): the
instance parity pin requires the whole instance surface. HostSchemaStub.New
is dot-defined with a placeholder receiver to keep luacheck clean.
Gates: luacheck 0/0; tests 326/326; perf exit 0, resolveUnchanged 0.0
B/iter; complexity gate (CCN 15) clean; settings/Schema.lua 387 lines.
Closes #14
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 1085966485e2173bd62d3e619834f6b4d3ad09f1
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:37:56 2026 +0530
PF-10: Route every event registration through LibKa0s SafeRegister*
Resolves PartyFrameEnhanced-A-03 (events-frames-taint-§1): registration
sites were bare loops, so one retired event name would drop every later
registration in the block, and nothing recorded the refusal.
- core/CoreSetup.lua publishes NS.SafeRegisterEvent / SafeRegisterUnitEvent
/ SafeRegisterEvents from LibKa0s-Core minor 8; the library-absent half
carries the Core version-8 doc's one-rung stubs (pcall, append once, no
C_EventUtils front gate).
- core/State.lua: host-owned NS.RejectedEvents.
- Every site routed with NS.RejectedEvents: the lifecycle loop and the
regen watcher (core/PartyFrameEnhanced.lua), Providers registerEvents
(now SafeRegisterEvents over the three burst events plus two singles),
CastBars per-unit loop, TargetFrames module events and UNIT_TARGET,
PetFrames RAID_TARGET_UPDATE and per-button unit events, RangeFade,
Preview listen().
- core/Bus.lua NS.BusStandUp also appends the record's refused event names
(the "event:<name>" entries) to NS.RejectedEvents, once each.
- /pfe status prints "Events the client refused: %s" when the list is not
empty (new enUS key).
- docs: midnight-quirks.md paragraph on the probing trade-off;
ARCHITECTURE.md Event Subscriptions says every row goes through
SafeRegister*.
- Tests (red first against the bare loops): a refused
EDIT_MODE_LAYOUTS_UPDATED across two disable/enable cycles leaves
PLAYER_REGEN_ENABLED and ADDON_LOADED on Providers.__ev and is recorded
once; a refused UNIT_SPELLCAST_DELAYED leaves the other twelve cast
events on the bar; /pfe status prints the refused line; the degraded
Core stub answers false on a raising target and appends once. The Core
parity case picks the three new publications up from the source.
docs/test-cases.md regenerated; README badge 320/320.
Deviations: the /pfe status test lives in tests/test_providers.lua (the
item names that file and test_castbars.lua; no separate slash suite case).
Line cites were stale after PF-09 (TargetFrames :232/:244, PetFrames
:117/:131-135, RangeFade :169, Preview :87-88); the intended sites were
routed. No version bump (item asks for none).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 01523f48066347d8fbafffe74d69a57a709f65cd
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:32:00 2026 +0530
PF-09: Hold module events only while needed; gate debug arguments
TargetFrames: PLAYER_TARGET_CHANGED and RAID_TARGET_UPDATE moved off file
load onto the module's bus target `ev` (hoisted above syncEvents), held by a
new syncModuleEvents(on) that syncEvents drives with its own answer
(feature on and in a party) and a module-local `moduleListening` flag, so
solo and feature-off pay no dispatch. PetFrames: the same for
RAID_TARGET_UPDATE. Preview: PLAYER_REGEN_DISABLED is registered by
listen(on) beside GROUP_ROSTER_UPDATE, so only while previewing; combat
still re-locks. The NS.Debug calls in TargetFrames' onEvent and PetFrames'
UNIT_PET branch are wrapped in `if NS.State.debug`, so UnitName is not
called to build a discarded argument.
Tests (red first, each confirmed failing on the old code): registration
set on TargetFrames.__ev / PetFrames.__ev across feature off, solo and back
in a party; Preview.__ev locked vs unlocked plus the combat re-lock; the
UnitName call count with debug off is one lower than with debug on.
test_disabled's baseline stays non-empty. docs/test-cases.md regenerated
(316), README badge 316/316, ARCHITECTURE Event Subscriptions rows updated.
Finding: PartyFrameEnhanced-R-17.
Deviations: line cites in the item were a few lines off (TargetFrames
debug at :212, events at :330/:336; Preview at :161); intent followed. The
event handlers are defined at the bottom of each file and bound through a
forward-declared local, since syncEvents only runs from OnEnable.
syncModuleEvents normalises its argument so syncEvents' CCN does not grow
(TargetFrames 7, PetFrames 9).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 4b372b48c9beb5c6bc911217df2d22118f17ebee
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:26:44 2026 +0530
PF-08: Run profile migration steps over every stored profile
Migration runner per WS-03 (savedvariables-§1). Resolves
PartyFrameEnhanced-R-15: the runner applied each step to the active
profile only, then stamped the account-wide schemaVersion, so the first
real step would have left every inactive profile unmigrated for good.
- defaults/Profile.lua: global.schemaVersion default 1 -> 0, with the
reason (AceDB strips a value equal to its default at logout, and
backfills a declared default onto an unstamped store).
- core/Database.lua: NS.SCHEMA_VERSION = 1 is the runner's target.
Ladder rows are { to, scope = "profile"|"global", apply }. A profile
step runs over every stored profile (lifted into targetsFor), a global
step over db.global, the whole step under pcall. On failure: logged
ungated via NS.DebugLog:Add("Migrate", ...), one localized line
printed, walk stops without stamping. On success the stamp advances
and NS.Debug logs "vA -> vB (N profiles)". After the walk the stamp is
raised to NS.SCHEMA_VERSION. NS.__schemaSteps is a test-only seam.
RunMigrations is CCN 8.
- locales/enUS.lua: the failure line's key.
- docs/schema.md: default 0, stamp 1 after the first run, the
per-profile and stamp-after-success rules.
- tests/test_database.lua: re-pinned the InitDB case (default 0, stamp
== NS.SCHEMA_VERSION); new cases inject a step over Default plus a
never-activated stored profile 'Second' (red under an active-profile-
only runner, confirmed by mutation), a raising step (stamp stays 1,
one line printed), and a rerun no-op. docs/test-cases.md regenerated,
README badge 310 -> 312.
Deviation: the item names NS.db.profiles. Real AceDB-3.0 exposes it
(dbmt __index, "profiles" section), but the vendored kit's AceDB fake
only exposes the raw table as db.sv.profiles, and tests/_kit/ is not
editable here, so targetsFor reads db.profiles or db.sv.profiles (the
same table in the client), falling back to { db.profile } on the
no-AceDB path. The test's 'Second' profile is created directly in the
raw stored table rather than through SetProfile, which is the case the
rule exists for and avoids a profile-switch side effect.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit a38504eb4c388982252c13a5372df4a0f51d6121
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:21:52 2026 +0530
PF-07: Print the collection's DisabledLine from the Lock-frame row
Finding PartyFrameEnhanced-A-08 (slash-commands-§7, the refusal line):
unticking Lock frame, or `/pfe set locked false`, while disabled printed
a gray "cannot unlock — the addon is disabled" (REFUSED_DISABLED). That
is a second wording of the one refusal. The verbs and the launcher
already printed cli:DisabledLine().
- settings/Slash.lua: publish NS.DisabledLine(), which asks
cli:DisabledLine() at call time. NS.ToggleLock uses it. The descriptor's
`set` wrapper still returns nothing; a comment now says a disabled
`/pfe set locked false` prints the refusal and then the echo, the same
shape as before.
- modules/Preview.lua: REFUSED_DISABLED is deleted. In NS.AcceptLock the
disabled branch (after the combat check) prints NS.DisabledLine() with
no gray, refreshes the panel and returns false. The combat and perf-
suspend refusals keep their gray lines. The header paragraph now says
the disabled refusal is the collection line.
- locales/enUS.lua: the 'cannot unlock — the addon is disabled' key is
deleted.
- tests: test_preview_standin's disabled arm now asserts that the refusal
is byte for byte the line the slash gate prints, contains
cli:DisabledLine() and is not gray. Its title changes from "one gray
line each" to "one line each". test_disabled has a new case: while
disabled, NS.SetByPath('locked', false) returns false, prints exactly
one line that matches the gate's line and contains cli:DisabledLine(),
and leaves profile.locked true. Both cases were run red against the
old Preview.lua and enUS.lua.
- docs/smoke-tests.md 10d: added the Lock frame checkbox step.
docs/test-cases.md regenerated (309 -> 310), README badge updated.
Deviations: the item says to print the line "unwrapped" and to assert
that the chat line equals cli:DisabledLine() byte for byte. Every other
surface (the slash gate, which is cli's `print`, and NS.ToggleLock)
prints through NS.Print, and NS.Print adds the [PFE] prefix. A bare
print would therefore give a line that no other surface prints. So the
refusal goes through NS.Print without the gray wrapper, and the tests
check that it is byte-identical to the slash gate's refusal of
`/pfe unlock` and that it contains cli:DisabledLine().
Gates: luacheck 0/0 in 72 files; tests 310 passed, 0 failed; inventory
in sync; tests/perf.lua exit 0; complexity scan at CCN 15 shows nothing;
largest authored .lua is 465 lines; the grep for REFUSED_DISABLED and
"the addon is disabled" in modules/ and locales/ returns nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 372518208b65e1363cd858ca71c499a713e98ea3
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:16:24 2026 +0530
PF-06: Pin the fade frames and holders hidden on stand-down
Finding PartyFrameEnhanced-A-01: the five PartyFrameEnhanced_Fade_*
frames and the three *_Holder frames stayed shown while the addon was
disabled.
The production half landed in PF-00 (e785003), and this commit checks it
is still there: RangeFade:Suspend/Resume hide and show the fade frames
through NS.RunSecure("fade:shown"), with Resume showing them before
update(). Anchor:Suspend/Resume do the same for every holder through
NS.RunSecure("holder:shown"). The RangeFade header's "never hidden"
sentence is already rewritten, and .luacheckrc already carries the
212/self stanza for modules/Anchor.lua. StandUp runs each("Resume")
before NS.PublishVisibility.
This commit adds what PF-00 left out:
- tests/test_disabled.lua: three new cases that look at the eight frames
directly (NS.RangeFade.Parent per unit and NS.Anchor.__features[k].holder)
rather than relying on the F_on baseline alone. After disable they are
hidden, after re-enable they are shown again, and in the in-combat case
a lockdown disable leaves them shown with the hide queued, and
PLAYER_REGEN_ENABLED then hides them. Each case was run red by
mutation: dropping the Suspend hides turns 3 red (including the existing
step-5 baseline check), dropping the Resume shows turns 2 red, and
bypassing RunSecure turns the combat case red.
- docs/ARCHITECTURE.md Taint Notes: the fade frame is never moved. It is
hidden on stand-down and shown on stand-up through RunSecure, so a
stand-down in combat is deferred until combat ends. The holders follow
the same rule.
- docs/test-cases.md regenerated (306 -> 309), README badge updated.
Deviations: the item's production change and the .luacheckrc stanza had
already landed in PF-00. This commit verifies them and does not change
them.
Gates: luacheck 0/0 in 72 files; tests 309 passed, 0 failed; inventory
in sync; tests/perf.lua exit 0; complexity scan at CCN 15 shows nothing;
largest authored .lua is 457 lines.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 433af1e22ab20490008a1cf2928420c8f80b83ea
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:12:12 2026 +0530
PF-05: Guard burst() while suspended and pin the EditMode.Exit callback
PF-00 already added editModeCallback(on) to modules/Providers.lua, behind
the existing EventRegistry presence guard and pcall. OnEnable and Resume
register the callback and Suspend unregisters it. PF-00 also made
test_disabled's sig() read r.target or r.owner. Both were verified here
(the mutation below turns step 3 red). This commit does the rest of the
item:
- modules/Providers.lua: burst() returns before it touches burstGen or
arms timers while `suspended`. There is no addon-side tracked-callback
helper (anti-pattern #85).
- tests/test_disabled.lua: step 3 carries the falsification comment
"red under: drop editModeCallback(false) from Providers:Suspend". A new
step after the timers step fires EventRegistry:TriggerEvent('EditMode.Exit')
while disabled and asserts no timer is armed.
- tests/test_providers.lua: the baseline has exactly one 'EditMode.Exit'
callback, owned by NS.Providers. The suspend case asserts the callback
comes off, a TriggerEvent arms nothing, and Resume brings it back once.
A new case captures the handler the stand-up registers and calls it
directly while suspended. It is red under: drop the suspended guard in
burst. Before the guard it failed with two follow-up timers armed.
- docs/ARCHITECTURE.md: added the Event Subscriptions row
`EditMode.Exit` (EventRegistry callback) | modules/Providers.lua, so the
"every registration except the last comes off" sentence holds. The
"What stands down" step 2 names the callback and the guard.
- docs/smoke-tests.md: new step 10g, the item's in-game smoke.
- docs/test-cases.md regenerated, README badge 306/306.
Mutations checked: removing editModeCallback(false) from Suspend fails
"every registration the addon owns is UNREGISTERED" (plus knock-ons).
Removing the burst guard fails the new test_providers direct-reach case.
Findings: PartyFrameEnhanced-R-03, PartyFrameEnhanced-R-10,
PartyFrameEnhanced-A-11.
Deviations: the item wanted the test_disabled TriggerEvent step marked
"red under: drop the suspended guard in burst". Because Suspend now
unregisters the callback, TriggerEvent while disabled cannot reach burst().
That step only goes red when both defences are dropped, and its comment
says so. The guard is falsified by the new test_providers case, which
reaches the captured handler directly (the same idea as test_disabled's
__fireUnconditional).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 8e723d15882d9ae37649dc3145f3c3b1a8b424af
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 09:06:05 2026 +0530
PF-04: Unregister the target/pet state drivers on stand-down
The stand-down replaced the ten target and pet buttons' secure visibility
drivers with "hide" instead of unregistering them, so the secure state-driver
manager kept evaluating ten conditions for an addon the player switched off
(slash-commands-§7). UnregisterStateDriver was declared in .luacheckrc but
never called.
- modules/UnitButtons.lua: new UnitButtons.Release(btn). It clears the
__driverWant request memo at request time, then through
NS.RunSecure('driver:' .. key) (ApplyDriver's key, so a queued install is
replaced) unregisters the visibility driver, hides the button and clears
__driver.
- modules/TargetFrames.lua, modules/PetFrames.lua: refresh() while suspended
sets __allowed = false and calls Release instead of ApplyDriver('hide').
Resume's refreshAll re-installs (the memo is nil). A feature that is merely
off keeps its "hide" driver. An in-combat stand-down queues the release and
the existing pending-secure regen watcher completes it.
- tests/test_disabled.lua: three new cases before the final one, each marked
red under "keep the hide driver": no visibility driver after an
out-of-combat disable; re-enable restores the pre-disable drivers
(preview "show", free placement); in combat the release queues
(PendingSecureCount > 0) and PLAYER_REGEN_ENABLED fired through the live
registry completes it, with the watcher letting go afterwards.
- tests/test_targetframes.lua, tests/test_petframes.lua: the perf-suspend
cases asserted the old "hide" driver; they now assert the driver is
unregistered while suspended and re-installed on release.
- docs/ARCHITECTURE.md "What stands down" step 2, docs/smoke-tests.md step
10f (review S-005), docs/test-cases.md regenerated, README badge 303/303.
.luacheckrc unchanged: UnregisterStateDriver now has a real use.
Finding: PartyFrameEnhanced-R-06.
Deviations: the ARCHITECTURE edit lands in the "What stands down" list of
"The disabled state is total" section (that is where the paragraph lives).
Test (b) compares against the pre-disable preview drivers under free
placement rather than the literal "[@party1target,exists] show; hide",
because this harness has no party frame system for attached placement;
the item allows the preview "show" alternative. Two existing suspend
cases were updated because they encoded the old behavior.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit 766d525a67c0f2801514c87f54952a1b9bf272f4
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 08:59:16 2026 +0530
PF-03: Compare secure-write memos against the requested value
UnitButtons.ApplyDriver and ApplyClicks skipped a write when the new
value equalled btn.__driver / btn.__clicks, which are set only inside
the deferred NS.RunSecure closure (the APPLIED state). In combat, a
setting changed and changed back therefore queued the first change and
dropped the second as "unchanged", so e.g. Click to target unticked and
re-ticked in combat came out OFF after combat.
The early return now compares request-side memos btn.__driverWant /
btn.__clicksWant, set at request time before NS.RunSecure; __driver and
__clicks stay the applied state. RunSecure keeps the latest write per
key, so the later request replaces the queued one. The file header's
SECURE RULES gains a bullet on the two memos.
Tests (red first, mutation-checked by reverting the early returns):
- targetframes: click to target unticked and re-ticked in combat stays
on after combat
- petframes: the same on the pet buttons
- targetframes: a driver changed and changed back in combat ends on the
last request
Smoke step 36a added; docs/test-cases.md regenerated; badge 300/300.
Finding: PartyFrameEnhanced-R-04
Deviation: the item's driver assertion (final __drivers.visibility after
OnLeaveCombat) is green even under the bug, because OnLeaveCombat
re-publishes visibility after the flush and heals the driver. The test
also records every driver installed while leaving combat and asserts it
is exactly the requested one, so the stale "hide" (a one-frame flicker)
is what goes red.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HTuhyvd3dgxDekBFUvKcoZ
commit e6d8dbce0f5511666462f5594fae670bc608638e
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 08:02:25 2026 +0530
PF-02: Read the live profile section in Anchor's config and slotSize
A profile switch, copy or reset could leave elements placed by the OLD
profile. Anchor re-applies on MSG.PROFILE through spec.config(), which
returned each feature's captured `cfg` upvalue; the feature re-binds
that upvalue only in its own PROFILE handler, and CallbackHandler-1.0
dispatches with next() over per-target tables, so handler order is hash
order and undefined. Whenever Anchor ran first it placed by the outgoing
profile, and nothing re-anchored afterwards.
- CastBars, TargetFrames and PetFrames now register
`config = function() return NS.db.profile.<key> end` and every
slotSize closure reads the same live section. The features keep their
own `cfg` upvalues for their own rendering, re-bound in their PROFILE
handlers as before. placementOf's shipped-default fallback stays.
- The comments at modules/Anchor.lua (placementOf) and
tests/test_anchor.lua no longer claim registration order equals
dispatch order.
- New suite tests/test_profile_switch.lua (after test_anchor): the
isolation case (bus stood down, SetProfile, Anchor.ApplyAll directly:
every element on the new profile's holder), a real SetProfile each
way, Reset all settings on a free profile, and CopyProfile of a free
profile. All four were red before the change; restoring the upvalue
config in TargetFrames alone turns the isolation case red again.
- docs/test-cases.md regenerated; README badge 297/297.
Findings: PartyFrameEnhanced-R-01; lands the real-switch coverage
PartyFrameEnhanced-R-08 asks for (with PF-01 and PF-03).
Deviations: the copy case copies into a fresh scratch profile rather
than over Default, so the suite leaves Default untouched; a fresh
profile is Default's shipped state, so the case is the same. The
CallbackHandler cite is lines 15-22 (Dispatch starts at 15).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube
commit 968ee1e7d930fa98dee7411ff0a4519e4ca9f36b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 07:56:00 2026 +0530
PF-01: Refuse bad names in the profile sub-verbs
`/pfe profile new <existing>` switched to that profile, reset it to
defaults and said "Created": a whole profile's data gone from one
ordinary command (PartyFrameEnhanced-R-02). The other name-taking
sub-verbs mishandled bad names too (PartyFrameEnhanced-R-05): `use`
went straight through SetProfile, which creates a profile out of any
typo; `copy` let AceDB-3.0's CopyProfile raise a raw Lua error on a
missing name or the current profile (:581-587); and `delete` passed
silent=true and printed "Deleted profile" for a profile that never
existed.
settings/Slash.lua gains an exists(db, name) helper over
db:GetProfiles(), and each verb checks it before touching AceDB:
- new refuses an existing name ("already exists", pointing at use/reset)
- use refuses a missing name
- copy refuses the current profile, then a missing name, before
db:CopyProfile (no pcall-and-print of the AceDB error)
- delete refuses a missing name after the existing current-profile check
Each refusal is one tagged line through NS.Print; the three new format
strings are in locales/enUS.lua's settings/Slash.lua key list. Every
verb function stays at CCN <= 3.
Player-facing, for the next Version History roll: `/pfe profile use`
no longer creates a profile, and `/pfe profile new` refuses a name that
already exists instead of wiping it; `copy` and `delete` refuse bad
names on one line instead of a Lua error or a false "Deleted".
Tests: four red-first cases in tests/test_slash.lua, one per defect,
run against kit revision 26's raising AceDB fake (LK-03). Each failed
for the right reason before the change (width 140 not 222; 'Typo'
created; raw "Cannot copy profile" raise; false "Deleted" line).
Mutation check: dropping the exists() guard in `new` fails case (a).
293/293, luacheck 0/0, no function above CCN 15, perf exit 0.
docs/test-cases.md regenerated and the README badge moved to 293. The
regeneration also picks up the § the v1.56.0 kit's own test names now
carry (test_prose, test_eol, test_layout_cap), which the RV-PF
re-vendor had left stale. docs/slash-dispatch.md's profile row states
the new refusals, and docs/smoke-tests.md gains step 20a for them.
Deviation: NO_PROFILE is held in one local constant and looked up as
L[NO_PROFILE] in its three call sites rather than spelled out three
times; the key itself is the item's string, registered in enUS.lua.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube
commit 4c2a1c64469391fb3566fcb6e2479f6bcc0c9768
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 07:52:20 2026 +0530
PF-00: address review — hide probe holders so the disabled census is deterministic
test_anchor's unregister() dropped a probe from Anchor.__features and
Anchor.__order but left its holder frame shown. Kit 26 creates frames
shown, and a probe outside `order` is out of Anchor:Suspend's reach, so
whether PartyFrameEnhanced_probeN_Holder landed in test_disabled's
baseline census depended only on whether the garbage collector had
already taken it (the kit's frame set is weak-keyed). With GC stopped,
or from a git-archive copy where the leak gate's full collect never
runs, "disabled: every frame that was on screen is hidden" failed every
time with "still shown: PartyFrameEnhanced_probe3_Holder".
unregister() now hides the probe's holder, so the census sees only
frames the addon really owns. Verified green with GC stopped and from a
git-archive copy; lint clean, 289/289 in the repo, no function above
CCN 15.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube
commit e785003eeeda649841cc7fe7b95f25c53ca109c5
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 07:46:00 2026 +0530
PF-00: Clear the nine kit-26 reds RV-PF recorded
RV-PF re-vendored LibKa0s v1.56.0 (kit revision 26) with 280 passed and
9 failed. All nine are green here (289 passed, 0 failed), with no assertion
weakened:
- providers: hidden member frames are skipped. The kit's CreateFrame now
starts frames shown (LK-05), so the fixture's `member(unit, {shown =
false})` now Hide()s the frame, as the client-side state it models.
- disabled: sig() read r.target, which the kit's new EventRegistry
`callback` records do not carry (LK-04). It now reads r.target or
r.owner and names the entry by __name, else by kind. This is the test
half of PF-05. Five knock-on reds (baseline, re-enabled, two holds, the
world left enabled, and "no game event", whose F_on the baseline fills)
go green with it.
- disabled: every registration UNREGISTERED. With sig() fixed, the
surviving 'callback|EditMode.Exit' entry is the red. modules/Providers.lua
gains editModeCallback(on) behind the existing EventRegistry presence
guard: OnEnable and Resume register it, Suspend unregisters it. This is
the editModeCallback part of PF-05 (finding PartyFrameEnhanced-R-03);
burst()'s suspended guard, the new EditMode.Exit/test_providers cases and
the ARCHITECTURE row are left to PF-05.
- disabled: every frame that was on screen is hidden. F_on now holds the
five PartyFrameEnhanced_Fade_* frames and three *_Holder frames. This
is the production part of PF-06 (finding PartyFrameEnhanced-A-01):
RangeFade:Suspend hides the fade frames and Resume shows them before
update(), both through NS.RunSecure("fade:shown"). New Anchor:Suspend
and Anchor:Resume hide and show every holder through
NS.RunSecure("holder:shown"). The RangeFade header's "never hidden"
sentence is rewritten. .luacheckrc gains the 212/self entry for
modules/Anchor.lua, as PF-06 foresaw. The direct step-5 IsShown()
assertions, the in-combat variant and the Taint Notes paragraph are
left to PF-06.
- optionssetup: Reset All sends PROFILE. This was a knock-on, not the
AceDB fake (LK-03) as RV-PF guessed. The "two holds" case raised in
sig() after lc:Hold("perf") and so left the perf hold taken. The addon
stayed stood down and no PROFILE reached the suite. It goes green with
the sig() fix, with no change to the case.
Gates: luacheck 0/0 in 71 files; lua5.1 tests/run.lua 289 passed,
0 failed; tests/perf.lua exit 0; the complexity scan at CCN 15 shows
nothing; no authored .lua file is above 1500 lines. The case count is
unchanged. The docs/test-cases.md drift in the two prose rows comes from
the kit's re-vendor and is left to PF-DOCS.
Finding ids: PartyFrameEnhanced-R-03 and PartyFrameEnhanced-A-01 (partial;
completed by PF-05 and PF-06). Deviations: RV-PF blamed the optionssetup
red on LK-03's AceDB fake, but it was a knock-on of the disabled suite.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube
commit 3edf817a58095cc2b00f5166605e3043ee539c28
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Sep 24 04:40:15 2026 +0530
RV-PF: Re-vendor LibKa0s v1.56.0 and record its delta bundle
Copy LibKa0s/ -> libs/LibKa0s/ and testkit/ -> tests/_kit/ whole from the
local LibKa0s tag v1.56.0 (git archive; rm -rf then copy; the runner keeps
mode 100755), and roll the CLAUDE.md provenance line v1.55.0 -> v1.56.0 in
the same commit. diff -r against the tag is empty for both payloads.
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 moves
revision 25 -> 26 and gains asserts.lua, mock_events.lua and prose_lists.lua.
No contract blockers: no host-supplied member's call site moved.
Writes docs/revendor/2026-09-23-v1.56.0/ (01_DELTA.md, 05_SUMMARY.md) per
the local wow-addon revendor-libka0s procedure as amended by WA-01. Adoption
decisions are not taken here; they are this addon's M3 items (PF-10, PF-11,
PF-12). docs/test-cases.md and the README test badge are left to PF-DOCS.
Gates: luacheck 0/0 in 71 files; lizard shows no function above CCN 15;
no authored .lua file above 1500 lines. Harness 280 passed, 9 failed
(baseline 289/0). The nine reds come from the stricter kit revision 26,
as the RV-* exception allows, and are cleared by M3 items (latest PF-DOCS):
- providers: hidden member frames and raid tokens are skipped
(CreateFrame starts frames shown, LK-05)
- disabled: the baseline; every registration UNREGISTERED; re-enabled
rebuilds; two holds, one latch; leaves the world enabled
(tests/test_disabled.lua:32 indexes r.target, nil on the kit's new
EventRegistry `callback` records, LK-04; PF-05)
- disabled: every frame that was on screen is hidden (8 frames now count
as shown, LK-05; PF-06/PF-04)
- disabled: no game event produces a write, a line, or a frame
(knock-on: F_on is filled by the failing baseline case; PF-05)
- optionssetup: Reset All resets the active profile only (the AceDB fake
now raises and strips defaults as AceDB-3.0 does, LK-03)
Finding ids: none (plan item RV-PF). Deviations: none.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ldej1stXpdhQLvEJxKqube
commit 4c2a7e6cb16095183c7e9c0cfbdc0cd84d491b32
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 20:50:42 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 8393eae2c4d23a1b20e1916a88261c896a2b6d83
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 16:51:21 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 8393eae2c4d23a1b20e1916a88261c896a2b6d83
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 16:51:21 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 25da95171bde798402ded1abc67065996642c067
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 15:16:48 2026 +0530
Record the v1.55.0 adoption decisions
docs/revendor/2026-09-23/ gains the candidates, the decisions, the
execution plan and the summary for the three new majors. Bus and Compat
are adopted (8a46028, d64703f). The Schema major is deferred as #14:
one attempt went green on every existing suite, but on a library-less
load it stopped /pfe enable, /pfe disable and /pfe lock from writing,
and a new pin caught that. The attempt was rolled back, and the
summary records the upstream question it raises.
ARCHITECTURE names Schema as vendored and not adopted yet, and counts
issues up to #14. test-cases.md is regenerated, and the README badge
moves to 289 cases.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx
commit 37207824ca3a6a246be1e221c34d84fd12d0bc5a
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 15:14:23 2026 +0530
Pin the write seam's behavior, and the library-less host-verb writes
These characterization cases were written for the LibKa0s-Schema-1.0
adoption. They are green on the host seam and stay after the adoption
was rolled back. They pin a write's order (store, one [Set] line,
onChange, CONFIG), a refused write that stores and calls nothing, a bulk
act that logs one line counting only changed rows, a bracket that closes
and re-raises by identity, the profile-reset count leaving out the
global minimap row, and the pre-db fallback to shipped defaults.
The last case pins a contract that settings/Slash.lua states and no test
held. On a load without LibKa0s the Master controls composer is hollow,
so `enabled` has no row, and /pfe disable and /pfe enable must still
land in the profile. The case went red under the adoption attempt,
because the Schema document's stub refuses a row-less path. That is why
the adoption was declined for now.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx
commit d64703fd8ecf317aaa160df8ab98a0a982747254
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 15:07:08 2026 +0530
Wire the secret guard from LibKa0s-Compat-1.0
Compat.IsSecret is now the library's member, and every other NS.Compat
member keeps calling it at call time, so no caller moves. Without the
library it falls back to the same one-rung body, the guard stub the
Compat document prescribes. A stub answering false would send a secret
into a comparison on a 12.x client, so the copy stays, with a comment
naming the document. The answer is now normalized as `f(v) and true or
false`, which matches the old `== true` for the client's boolean.
A characterization case pinning exact arity and boolean answers went in
green on the host body first. The new cases show that the live member is
the library's, and that the degraded load's stub answers what the
library answers under the same issecretvalue fixture. NS.Compat is held
to the major by name, with the eight members this addon does not wire
listed, through a new surface-source row. The ARCHITECTURE overview now
counts eleven consumed majors at v1.55.0, and compat-layer.md names the
library for IsSecret.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx
commit 8a46028b08c65fee3548ea116916aaf1cfa51054
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 15:05:03 2026 +0530
Move the bus stand-down record onto LibKa0s-Bus-1.0
core/Bus.lua's hand-written record becomes one Bus:New{} instance, with
isDown asking NS.IsStoodDown at call time. NS.NewBusTarget,
NS.BusStandDown and NS.BusStandUp keep their names as one-line
delegates, so no module moves, and NS.MSG is now Bus.Catalog's strict
table. The publisher stays host code.
This fixes the record's key list, which gained an entry on every
re-register after an unregister: RangeFade's range-event toggle and
Providers' Suspend/Resume grew it for the whole session. It also drops
the mojibake the old comments carried. Two semantics move the way
slash-commands-§7 asks: a registration made while stood down is
recorded and goes live at the stand-up, and a stand-up is refused while
the latch still reads down.
Characterization cases for the round trip went in green on the old
record first. The pins for the fix, the while-down deferral and the
strict catalog were red on it. Without the library, core/Bus.lua takes
the untracked-target stub the Bus document prescribes. The degraded
cases pin that stub and its stated limitation (a disable leaves bus
registrations live), and the parity case holds it to the major by name
through a new surface-source row. ARCHITECTURE names the major and the
limitation.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx
commit e3311351ded35d9320f7e583a1d6f6f55705031b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 14:53:12 2026 +0530
Re-vendor LibKa0s v1.55.0
Both payloads copied whole from the v1.55.0 tag, with the CLAUDE.md
provenance line rolled in the same commit. The library gains three
unconsumed majors (Compat, Bus, Schema) and their LibKa0s.xml rows; every
existing file's minor is unchanged, so nothing this addon looks up moved
and the delta found no contract blocker. The kit moves from revision 24
to 25 and brings the layout-§1 cap census gate, which tests/run.lua now
wires in the pair form testing-§9 prescribes. The delta read is recorded
in docs/revendor/2026-09-23/01_DELTA.md.
The docs follow: testing.md names the three kit suites, DEPENDENCIES.md
the new gate's use of git, the documentation map the revendor bundles,
and test-cases.md and the README badge move to 268 cases.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx
commit 134d18ced65ff7fc3dbc13bbd6c305f824753782
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 14:49:50 2026 +0530
Add the cap census heading, and stop naming the retired spelling suite
docs/ARCHITECTURE.md gains the `### Files over the 1500-line cap` census
under its deviations register, empty as a result: the largest authored
Lua file is settings/Slash.lua at 437 lines. docs/testing.md and
DEPENDENCIES.md named tests/test_spelling.lua, which the kit's
tests/_kit/test_prose.lua replaced; both now name the kit suite.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx
commit dd14a4e9a0bb52ff2bc781f696acf2b4e8039c0d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 23 11:33:35 2026 +0530
Refresh the standards reference to v2.63.0
- .gitattributes: brought to line-endings-§5's canonical client-bound body
byte-for-byte; adds the *.py text eol=lf carve-out and the shebang
comment that now covers tools/ generators. No renormalization needed:
0 worktree stragglers before and after.
- CLAUDE.md: Standards compliance item 1 restored to the canonical
substance (Rule is the filename-§N reference; the reasoning may live in
the issue-audit issue or an audit bundle and the row cites it).
Notation sweep: 18 dotted hits remain, all citing the addon's own design
spec (docs/superpowers/specs/...), not the standard. No malformed or
out-of-range filename-§N references.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TTuxA9sSHE1H7JLgJ4kYAx
commit 7eea3d06c73dae29b332a698e9cb72eba98b79ef
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 22 21:05:11 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 dd14677f8226987d22cd458a5b0a06d090f10930
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 22 19:38:52 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 5a668c1f94f610cebd715bafc575d19c9974db83
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 22 18:06:34 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 2a18e3be546dceb4717702f54f57cfcff6bc8976
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 22 17:12:25 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 382b928fded58712026b7e4a4c5603a1e5f37ea7
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 22 10:23:10 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 72 files; 241 passed, 0 failed, 0 skipped, 241 total
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk
commit e1fcef92970af518eaaa3f042461131f71ff181f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 22 02:25:53 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 72 files; 241 passed, 0 failed, 0 skipped, 241 total
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk
commit 86f03491ecfd82185ad5f8872975071a3ee461b8
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Mon Sep 21 15:45:32 2026 +0530
Say v1.50.0 where the docs still said v1.47.0
The re-vendor rolled the CLAUDE.md provenance line, which is the one
tests/test_vendor_sync.lua reads, but docs/ARCHITECTURE.md carries its
own current-state statement of which LibKa0s this addon bundles and
nothing gates that one. It was left at v1.47.0.
Found by a post-re-vendor sweep for version claims that describe the
CURRENT state rather than naming when a feature arrived; the historical
references ("since the v1.42.0 re-vendor", "LibKa0s v1.45.0's shownWhen")
are correct as written and untouched.
Gate: lint 0 warnings / 0 errors in 72 files; 241 passed, 0 failed, 0 skipped, 241 total
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk
commit 997758715e6c88704c34ae6415037e8d1b78e103
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Mon Sep 21 14:56:24 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 72 files; 241 passed, 0 failed, 0 skipped, 241 total
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk
commit f14b09648723605fcd025cd66d55a5e1e48eb9cd
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 20 19:55:44 2026 +0530
Re-vendor LibKa0s v1.47.0
Both payloads replaced whole from the v1.47.0 tag -- libs/LibKa0s/ and
tests/_kit/ -- with the CLAUDE.md provenance line rolled in the same
commit, so the vendored-payload gate compares against the tag it names.
Only OptionsWidgets.lua moved; the test kit is byte-identical to the one
v1.46.1 shipped. ARCHITECTURE.md's library line and build status name
v1.47.0.
The release's one new surface, O.IdList's `columns`, is NOT adopted, and
there is nothing to weigh: this addon has no O.IdList or H.IdList call
site. The only mention of the name is the degraded-build no-op stub in
settings/OptionsSetup.lua, and the profile stores no id collection of
any kind -- the schema is toggles, sizes, anchors and colors. A second
column packs long lists; there is no list.
green: tests 241/0/241, luacheck 0/0 in 72 files. No version bump.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk
commit f14b09648723605fcd025cd66d55a5e1e48eb9cd
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 20 19:55:44 2026 +0530
Re-vendor LibKa0s v1.47.0
Both payloads replaced whole from the v1.47.0 tag -- libs/LibKa0s/ and
tests/_kit/ -- with the CLAUDE.md provenance line rolled in the same
commit, so the vendored-payload gate compares against the tag it names.
Only OptionsWidgets.lua moved; the test kit is byte-identical to the one
v1.46.1 shipped. ARCHITECTURE.md's library line and build status name
v1.47.0.
The release's one new surface, O.IdList's `columns`, is NOT adopted, and
there is nothing to weigh: this addon has no O.IdList or H.IdList call
site. The only mention of the name is the degraded-build no-op stub in
settings/OptionsSetup.lua, and the profile stores no id collection of
any kind -- the schema is toggles, sizes, anchors and colors. A second
column packs long lists; there is no list.
green: tests 241/0/241, luacheck 0/0 in 72 files. No version bump.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YRNj7EQPJHjuxLUH6jv4xk
commit 49fb10aaa1f98bcb911c88dda7475b4b13cf7e97
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 20 02:27:00 2026 +0530
Build status names v1.0.1 as the latest release and lists what master adds
"Feature-complete for v1.0.1" stopped being true once the range fade,
the pet and over-the-border raid markers, the shown-only placement block
and LibKa0s v1.46.1 landed on master after the tag. The status now says
v1.0.1 is the latest release and names that unreleased work, which
waits for the next version bump.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WkU3isSkvWPZkWVr51uZKo
commit 996570f94d64087b65f35d755d61e5dbc98164c8
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Sep 20 02:13:54 2026 +0530
Docs follow LibKa0s v1.46.1's combat lock and the shown-only placement block
The settings window no longer closes in combat: a page on screen goes
under the library's gray cover and refuses writes until combat ends.
Smoke step 16, the taint notes, the settings-panel intro and the README
troubleshooting row now say so, and the hub names v1.46.1. The README's
"the other placement grays out" line now matches shownWhen, which draws
only the active block. test-cases.md regenerated (targetframes 21).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WkU3isSkvWPZkWVr51uZKo
commit d40aee969cef84dca94a2ada7453088b04ca3259
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 19 21:46:57 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 d40aee969cef84dca94a2ada7453088b04ca3259
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 19 21:46:57 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 f104e43b8dda78ffd6582e6d2705425de6cfe3b9
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 19 18:16:00 2026 +0530
Raid marker draws above the border; pet frames get one; default anchor Top
The marker was a region of the bar, and every child frame of the bar --
the border included -- draws above the bar's own regions, so the border's
edge cut across it. It now sits on its own layer one frame level above
the border (not on the border frame, which hides with Show border off).
Pet frames build the same marker: painted on UNIT_PET, repainted on
RAID_TARGET_UPDATE (the module's own target), a skull in preview, and a
Marker tab with Show raid marker / Anchor point / X and Y offsets.
Both features' marker now defaults to TOP of the bar.
Tests: 241 (4 new); the mock records frame levels. Docs follow.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WkU3isSkvWPZkWVr51uZKo
commit f104e43b8dda78ffd6582e6d2705425de6cfe3b9
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 19 18:16:00 2026 +0530
Raid marker draws above the border; pet frames get one; default anchor Top
The marker was a region of the bar, and every child frame of the bar --
the border included -- draws above the bar's own regions, so the border's
edge cut across it. It now sits on its own layer one frame level above
the border (not on the border frame, which hides with Show border off).
Pet frames build the same marker: painted on UNIT_PET, repainted on
RAID_TARGET_UPDATE (the module's own target), a skull in preview, and a
Marker tab with Show raid marker / Anchor point / X and Y offsets.
Both features' marker now defaults to TOP of the bar.
Tests: 241 (4 new); the mock records frame levels. Docs follow.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WkU3isSkvWPZkWVr51uZKo
commit ea6f8ffe11ba3774c9f69574c398eb65109d8fb2
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 19 16:45:28 2026 +0530
Size & Position draws only the placement block the anchor mode uses (LibKa0s shownWhen)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019uT32jXujZ279wBVAwHhEU
commit ea6f8ffe11ba3774c9f69574c398eb65109d8fb2
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 19 16:45:28 2026 +0530
Size & Position draws only the placement block the anchor mode uses (LibKa0s shownWhen)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019uT32jXujZ279wBVAwHhEU
commit c2577a5ca955f51ca85df313031f5e3e159c1875
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 19 16:33:19 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 adopts it next, on
feat/switched-sections (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: 235 passed, 0 failed, 0 skipped (vendor-sync compared against v1.45.0); lint 0/0;
complexity check no new warning; perf green.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019uT32jXujZ279wBVAwHhEU
commit 6e2f387b3419a6cbafb319d9e9b1a3a4c5b96ccc
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 19 10:00:21 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). Provenance line moved in CLAUDE.md and the
version quoted in docs/ARCHITECTURE.md's substrate line.
Battery: lua tests/run.lua 235 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; tests/perf.lua runs clean.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019uT32jXujZ279wBVAwHhEU
commit 6e2f387b3419a6cbafb319d9e9b1a3a4c5b96ccc
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Sep 19 10:00:21 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). Provenance line moved in CLAUDE.md and the
version quoted in docs/ARCHITECTURE.md's substrate line.
Battery: lua tests/run.lua 235 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; tests/perf.lua runs clean.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019uT32jXujZ279wBVAwHhEU
commit 402312ad7c37a465b9907062e50396a288c72003
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Sep 18 17:04:52 2026 +0530
Every element fades with its party member's frame when they're out of range
THE FEATURE. A member who walks out of range now has their cast bar, target
frame and pet frame dim along with their party frame. It is on by default,
behind General -> Party frames -> "Fade with party frames"
(general.rangeFade).
HOW EACH FRAME SYSTEM IS FOLLOWED (modules/RangeFade.lua):
- EllesmereUI and Blizzard raid-style fade their own member frames, so the
fade is copied. Each member frame's SetAlpha and SetAlphaFromBoolean are
post-hooked and the same call is replayed. The copy is exact, including
EllesmereUI's own out-of-range alpha, its offline and phased alphas, and
Blizzard's 0.5.
- Blizzard classic's PartyMemberFrame never fades for range, so there is
nothing to copy. The module asks UnitInRange itself on
UNIT_IN_RANGE_UPDATE and fades to 0.5. The event is registered only while
the fade is on, in a party, on those frames.
ONE FADE FRAME PER UNIT. Every element is parented to its unit's plain fade
frame at creation, and only that frame's alpha changes. The client
multiplies it in, so each element keeps its own alpha: Master alpha, the
mid-combat reshuffle fade, the cast bar fade-out. That split is required,
not tidy: the copied alpha can be secret, and a secret cannot be multiplied
in Lua. A secret flag goes to SetAlphaFromBoolean untouched. A secret number
is tried on SetAlpha under pcall, falling back to a raid-style frame's own
outOfRange flag. The fade frame's GetAlpha is never read back.
Full alpha when the setting is off, in preview, while suspended, and for a
unit with no party frame. /pfe status gains a "Range fade:" line.
Spell-based ranges and a per-feature opacity slider are #13, the follow-up
asked for alongside this.
TESTS: tests/test_rangefade.lua, 8 cases. Each runs between two resets, so a
failure cannot leak its fixture into later suites. Every fade path was
proven red by disabling it. The mock now records every frame's alpha calls
and answers UnitInRange. The schema counts in test_optionssetup move by the
one new row. 235/235, lint 0/0; offline perf API and byte counts unchanged.
DOCS: ARCHITECTURE (overview, file count, bus consumers, events, taint
notes, known limitations), module-map (row 21), data-flow (a new stage 4),
schema, settings-panel, slash-dispatch, scope, midnight-quirks, testing
(the lint config's per-file stanzas), smoke steps 47a-47d, the regenerated
test-cases, and a README paragraph plus the Tests badge.
Not yet verified in game.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KHAvXxAQktWcUeGFGN2q5A
This mod has no additional files

