1.5.0-release
What's new
tag fe84dfb3391843ec70e7233be5daba3193b5cb6f 1.5.0-release
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Oct 9 19:26:44 2026 +0530
Release 1.5.0
commit 0990fdc7973ed6e5bc7bfdce036375ec350ce81c
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Oct 9 19:21:55 2026 +0530
Release 1.5.0: version bump, release notes and the gated release run
Version 1.4.0 -> 1.5.0 in KickCD.toc (## Version) and core/KickCD.lua
(NS.VERSION). The launcher test reads the TOC, so no test pins a literal.
Release gate, read from docs/automated-tests/20261009-191808/manifest.json
(run with --release 1.5.0 at c6470e7), all six pass:
- Lint: pass, 0 warnings / 0 errors in 127 files
- Tests: pass, 1319 passed, 0 failed, 1 skipped (a kit diagnostics
contract branch this addon does not take), 1320 total
- Perf: pass, 7 scenarios measured
- Complexity: pass, lizard 1.24.0, 26160 NLOC / 3616 functions, avg CCN 2.1
- CCN <= 15: 0 warnings, max CCN 15
- Sighted: blindFiles 0 (first sighted run in this record)
Files:
- KickCD.toc, core/KickCD.lua: the version stamp
- README.md: new 1.5.0 row at the top of Version History (/kcd profile,
the target-casting glow for any cast, UTF-8 cast bar truncation, the
cast bar anchor on an empty grid, drag strip tooltips and the Spells
list gap)
- docs/automated-tests/20261009-191808/: the release bundle, with its
ANALYSIS.md
- docs/automated-tests/RESULTS.md: the run's row and the watch list
refreshed to this run (no function above CCN 15; no file in the
1000-1500 band, all nine formerly tracked files #24-#32 peeled out)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J2w6FgfFYw93meWZN9Ahn6
commit c6470e76397c3265d94622d7027217c19143b042
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Oct 9 18:53:21 2026 +0530
SD-FIN-03: remove dead test seam Helpers.__gridCtx
Zero callers anywhere; no doc or surface pin named it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J2w6FgfFYw93meWZN9Ahn6
commit 31c0de19088e463eae1f09feec87a3b778ee665d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Oct 9 17:49:30 2026 +0530
SD-FIN-02: sync docs to code (collection sync-docs pass 2026-10-09)
Docs and comment citations reconciled against today's tree: stale counts,
drifted file:line citations, orphan anchors and toolchain gaps, each verified
independently before applying. Comment edits are comment-only. Dead-export
candidates reported, not removed. Green gate run after the edits.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J2w6FgfFYw93meWZN9Ahn6
commit 0ca71f00114d6c6e87652d4cbea6b92b91efcb41
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Oct 7 22:21:15 2026 +0530
KC-STD: Roll the standards reference to v2.77.0 and sync the KC docs
Standards reference (wow-revendor-standards procedure, against
WowAddonStandards feat/2026-10-07-review-audit-remediation at ffcb11a,
standard v2.77.0):
- Three places checked: KickCD.toc ## X-Standard, the README Standard
badge (bare image, not a link) and CLAUDE.md "Standards compliance
(read first)" already carry the canonical, version-free form; v2.77.0
did not change it, so none moved.
- Retired notation: zero dotted global section numbers in the live tree
(excluding libs/, tests/_kit/ and the frozen audits, reviews,
automated-tests, revendor, superpowers and perf-analysis bundles).
Range check: 934 filename-§N citations, every one resolving against
v2.77.0's section files; the only two non-parsing hits are the
canonical block's literal `filename-§N` placeholder.
- WS-08 (versioning-git branch wording): no live doc restates trunk-only
prose; CLAUDE.md's "never auto-stage/commit/push" stays true. WS-03:
no live doc restates the shebang carve-outs; .gitattributes already
carries both. No live doc names a "current" standard version; the
"standard v2.54.0/v2.65.0/v2.67.0 introduced X" citations stay (history).
- WS-07 citation form: four comments cited the vendored LibKa0s payload
by bare line number, and all four had drifted after the v1.71.0
re-vendor (PerfPanel.lua:185-196, Options.lua:210, DebugLog.lua:477,
:482). Comment-only, they now cite by symbol: core/PerfSetup.lua,
tests/test_perfsetup.lua, tests/test_constants.lua,
tests/test_surface_parity.lua.
Docs sync of KC-01..KC-10:
- docs/castbar.md: the GRID_LAYOUT cache keeps primaryIcon verbatim, nil
included, so a PRIMARY bar on an empty grid falls back to the grid
frame (KC-01).
- docs/schema.md: nameTruncate counts UTF-8 characters, not bytes (KC-02).
- docs/debug.md: the diagnostics icongrid row names the three cached
glow-gate scalars, `any` included (KC-03).
- docs/module-map.md: Util.Throttle's zero-argument EMPTY_ARGS sentinel
and its Cooldowns coalescer caller (KC-06).
- docs/ARCHITECTURE.md: /kcd debug's unknown word refuses without the
toggle, and castbar/interrupt take an optional target/focus word (KC-04).
- docs/smoke-tests.md: new GRID-18 (KC-03), CAST-16 (KC-01) and LOC-7
(KC-02), index ranges moved; DIAG-2 and SLASH-14 (already extended by
KC-04) get Pending sign-off rows saying so. All recorded unrun.
- Already in place and verified: icon-grid.md, data-flow.md (KC-03),
slash-dispatch.md, debug.md castbar/interrupt sections and README FAQ
(KC-04), schema.md/module-map.md/ARCHITECTURE.md SCHEMA_VERSION (KC-05),
DEPENDENCIES.md (KC-07), the KC-08/KC-09 edits.
docs/test-cases.md regenerated with no change: Total 1319 equals the
README Tests badge 1319/1319. No version bump, no CHANGELOG section.
Findings: none directly (item carries no finding ids); docs sync for
KC-R-01..05, KC-A-04.
Deviations: the WS-07 SHOULD speaks of another repo's code; the four
fixed citations point into this repo's vendored copy of LibKa0s, which
is that repo's code, and had all gone stale, so they were converted
(comment-only). The item named docs/slash-dispatch.md and README for
sync; both were already current after KC-04 and were left unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoCGDEVoaSdzqSHHsASPMi
commit 0ca71f00114d6c6e87652d4cbea6b92b91efcb41
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Oct 7 22:21:15 2026 +0530
KC-STD: Roll the standards reference to v2.77.0 and sync the KC docs
Standards reference (wow-revendor-standards procedure, against
WowAddonStandards feat/2026-10-07-review-audit-remediation at ffcb11a,
standard v2.77.0):
- Three places checked: KickCD.toc ## X-Standard, the README Standard
badge (bare image, not a link) and CLAUDE.md "Standards compliance
(read first)" already carry the canonical, version-free form; v2.77.0
did not change it, so none moved.
- Retired notation: zero dotted global section numbers in the live tree
(excluding libs/, tests/_kit/ and the frozen audits, reviews,
automated-tests, revendor, superpowers and perf-analysis bundles).
Range check: 934 filename-§N citations, every one resolving against
v2.77.0's section files; the only two non-parsing hits are the
canonical block's literal `filename-§N` placeholder.
- WS-08 (versioning-git branch wording): no live doc restates trunk-only
prose; CLAUDE.md's "never auto-stage/commit/push" stays true. WS-03:
no live doc restates the shebang carve-outs; .gitattributes already
carries both. No live doc names a "current" standard version; the
"standard v2.54.0/v2.65.0/v2.67.0 introduced X" citations stay (history).
- WS-07 citation form: four comments cited the vendored LibKa0s payload
by bare line number, and all four had drifted after the v1.71.0
re-vendor (PerfPanel.lua:185-196, Options.lua:210, DebugLog.lua:477,
:482). Comment-only, they now cite by symbol: core/PerfSetup.lua,
tests/test_perfsetup.lua, tests/test_constants.lua,
tests/test_surface_parity.lua.
Docs sync of KC-01..KC-10:
- docs/castbar.md: the GRID_LAYOUT cache keeps primaryIcon verbatim, nil
included, so a PRIMARY bar on an empty grid falls back to the grid
frame (KC-01).
- docs/schema.md: nameTruncate counts UTF-8 characters, not bytes (KC-02).
- docs/debug.md: the diagnostics icongrid row names the three cached
glow-gate scalars, `any` included (KC-03).
- docs/module-map.md: Util.Throttle's zero-argument EMPTY_ARGS sentinel
and its Cooldowns coalescer caller (KC-06).
- docs/ARCHITECTURE.md: /kcd debug's unknown word refuses without the
toggle, and castbar/interrupt take an optional target/focus word (KC-04).
- docs/smoke-tests.md: new GRID-18 (KC-03), CAST-16 (KC-01) and LOC-7
(KC-02), index ranges moved; DIAG-2 and SLASH-14 (already extended by
KC-04) get Pending sign-off rows saying so. All recorded unrun.
- Already in place and verified: icon-grid.md, data-flow.md (KC-03),
slash-dispatch.md, debug.md castbar/interrupt sections and README FAQ
(KC-04), schema.md/module-map.md/ARCHITECTURE.md SCHEMA_VERSION (KC-05),
DEPENDENCIES.md (KC-07), the KC-08/KC-09 edits.
docs/test-cases.md regenerated with no change: Total 1319 equals the
README Tests badge 1319/1319. No version bump, no CHANGELOG section.
Findings: none directly (item carries no finding ids); docs sync for
KC-R-01..05, KC-A-04.
Deviations: the WS-07 SHOULD speaks of another repo's code; the four
fixed citations point into this repo's vendored copy of LibKa0s, which
is that repo's code, and had all gone stale, so they were converted
(comment-only). The item named docs/slash-dispatch.md and README for
sync; both were already current after KC-04 and were left unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoCGDEVoaSdzqSHHsASPMi
commit d1a32a8aa241113ceefcd42448d435619bba8a9a
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Oct 7 20:45:34 2026 +0530
KC-09: Qualify standalone bare §N citations in tests and live docs
documentation-§6 (as WS-07 restates it) asks each standalone section
citation to name its section file. Comment and doc text only; no
behaviour change and no test_source_style guard (per the verdict).
- tests/test_flow_traces.lua: the twelve standalone §8/§9 sites
(:28, :52, :68, :83, :110, :133, :145, :216, :228, :258, :275, :318)
now read debug-logging-§8 / debug-logging-§9.
- tests/test_library_lines.lua:97 -> debug-logging-§8.
- docs/settings-panel.md:62 -> options-ui-§7, :203 -> options-ui-§14.
- docs/slash-dispatch.md:71 and :98 (cited as :70/:97) ->
slash-commands-§7.
Left as they are: same-sentence continuations at
test_flow_traces.lua:22 and slash-dispatch.md:118, plus
docs/smoke-tests.md's own retired section numbers.
Finding: KC-A-03.
Deviation: docs/slash-dispatch.md:241 also had a standalone bare §5,
which the audit did not list. It is now slash-commands-§5 (settings
read/write output format), so the item's verify grep leaves only
qualified citations or same-sentence continuations.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoCGDEVoaSdzqSHHsASPMi
commit 460c7a4e1781bc5e4b61a445be8e042f557675de
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Oct 7 20:42:09 2026 +0530
KC-08: Name rules, not counts, in four drifted inventories
Resolves KC-A-02 (documentation-§5 count drift). Each site carried a
count or closed list that had already gone stale:
- docs/ARCHITECTURE.md: drop "Eight do" / "The other thirty-six" and the
closed file list (settings/OptionsSetup.lua was missing from it). State
the rule instead -- a file reads the first vararg only to hand the
folder name to a vendored LibKa0s payload that cannot infer it -- and
give the git grep that lists the files today.
- .luacheckrc: the M4c-06 history comment keeps the historical
twenty-nine (past tense) and drops the present-tense "Eight files" and
"thirty-three authored files" counts, pointing at the ARCHITECTURE rule.
- docs/compat-layer.md: NS.State.SetInCombat is called from core/State.lua's
combat listener, an AceEvent target armed by State.Arm (re-armed and
re-seeded by State.StandUp), not a bootstrap CreateFrame.
- .pkgmeta: drop "Seven files, 7.5M" and the size claim; the
media/screenshots art is project-page material the CurseForge CDN serves.
Deviation: the compat-layer row also names State.StandUp, because it is
a second SetInCombat caller in the same file and "called only by the
listener" would otherwise be a new inaccuracy.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoCGDEVoaSdzqSHHsASPMi
commit 619f277537a32f2a29bbb9015fdf97871205f14d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Oct 7 20:38:51 2026 +0530
KC-07: Trim .luacheckrc read_globals to names a linted file reads bare
Resolves KC-R-08 (review F-008, continuing F-016). The top-level
read_globals carried 44 names that no linted file reads bare, so a new
bare call to any of them (for example the legacy UIDropDownMenu_AddButton)
would have linted clean.
Census (git grep -nwE '(^|[^._A-Za-z0-9"])NAME' over linted .lua, i.e.
excluding libs/, tests/_kit/, docs/audits/, docs/reviews/, _dev/, with
comment lines dropped): 0 bare readers for all 44 names, except three
hits that are not reads: _G (every hit is an _G.X field access, and _G is
already in std lua51), UnitChannelInfo (inside a help string in
core/KickCD.lua:415) and time (inside a message string in
tests/test_color_shape.lua:542).
Removed: _G, GetTime, GetTimePreciseSec, GameFontNormal,
GameFontHighlight, GameFontDisable, STANDARD_TEXT_FONT, hooksecurefunc,
securecallfunction, issecretvalue, C_Timer, C_Spell, C_SpecializationInfo,
GetLocale, InCombatLockdown, PlaySound, UnitCastingInfo, UnitChannelInfo,
UnitExists, UnitCanAttack, UnitGUID, UnitName, UnitIsDead, IsLoggedIn,
UISpecialFrames, UIDropDownMenu_AddButton, CreateColorFromHexString,
WrapTextInColorCode, CopyTable, wipe, tContains, tinsert, tremove,
strsplit, strtrim, strjoin, date, time, BackdropTemplateMixin,
CreateFromMixins, NORMAL_FONT_COLOR, HIGHLIGHT_FONT_COLOR, RED_FONT_COLOR,
GREEN_FONT_COLOR. The 24 bare-read names stay. luacheck . stays 0/0 with
nothing to restore. No files["tests/"] read_globals stanza was added.
Group headings regrouped so none is left empty ("fonts / textures used
in DebugLog / panels" went with its names).
Ripples: DEPENDENCIES.md cite .luacheckrc:48-79 -> :48-68, and the
tests/wow_mock.lua comment that said `date` is in read_globals now says
it no longer is. tests/test_lintconfig.lua pins no removed name, so it
is unchanged; test count unchanged (1319 passed, 1 skipped), so
docs/test-cases.md and the badge need no regeneration.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoCGDEVoaSdzqSHHsASPMi
commit 0b42a855851bf2cc2116a37e08d5bcc1e5464ee3
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Oct 7 20:34:50 2026 +0530
KC-06: reuse a frozen empty-args sentinel for zero-arg Throttle calls
Util.Throttle packed `{ n = select('#', ...), ... }` on every wrapped()
call, including the zero-argument calls Cooldowns' refresh coalescer makes
on every SPELL_UPDATE_COOLDOWN / _USABLE / _CHARGES: one throwaway table per
event in combat. A file-scope `EMPTY_ARGS = { n = 0 }`, never written to,
now stands in when select('#', ...) == 0; fire() only reads args.n and
unpacks, so sharing it is safe. Calls with arguments still get a fresh
table per burst, and the closure comment now names the sentinel and why it
is safe.
Tests (characterization, green before and after the change):
- a zero-argument throttle fires fn once per burst with no arguments
- a zero-arg burst after an args burst does not leak the old args
docs/test-cases.md regenerated and the README Tests badge moved to
1319/1319. No perf scenario added, per the verified verdict on KC-R-09.
Finding: KC-R-09
Deviation: the sentinel's explanatory comment sits above the function's
`---` doc block rather than inside it, so the doc block stays attached to
Util.Throttle.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoCGDEVoaSdzqSHHsASPMi
commit ef6ec90ef86bf7ff8b1bf92b399ed47a7cfc7095
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Oct 7 20:28:36 2026 +0530
KC-05: publish the migration target as NS.SCHEMA_VERSION; drop the alias
savedvariables-§1 names the runner's target NS.SCHEMA_VERSION, the
spelling the other ten addons use. KickCD kept it as a file-local
CURRENT_DB_VERSION republished as Database.CURRENT_DB_VERSION.
- core/Database.lua publishes NS.SCHEMA_VERSION = 5 (value unchanged, no
stored data changes) and no longer sets Database.CURRENT_DB_VERSION.
- core/Database_Migrations.lua reads NS.SCHEMA_VERSION; the runner loop
and the missing-step jump use it; comments renamed.
- modules/Diagnostics.lua's state section prints schema stored vs
NS.SCHEMA_VERSION.
- tests: new tests/test_database.lua case pins NS.SCHEMA_VERSION == 5, a
fresh install stamped with it, and the alias gone (red on HEAD: got
nil); test_diagnostics reads NS.SCHEMA_VERSION; comments and the
test_color_shape red-under note renamed.
- docs: ARCHITECTURE.md, module-map.md (incl. "this file publishes
NS.SCHEMA_VERSION"), schema.md renamed; frozen bundles untouched.
- docs/test-cases.md regenerated and README Tests badge moved to
1317/1317 (Total row 1317).
Finding: KC-A-04.
Deviation: the optional "NS.SCHEMA_VERSION == #steps + 1" pin was not
added, because Database_Migrations keeps its step table file-local and
the item asks for it only if the table is exposed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoCGDEVoaSdzqSHHsASPMi
commit ffcb11aea6aa77ef3988546dda348928df4faaef
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Oct 7 20:23:43 2026 +0530
KC-04: /kcd debug refuses an unknown word untoggled; castbar takes focus
An unknown /kcd debug word used to refuse and then re-enter runDebug(self, ""),
which toggled the debug console, so a typo such as `/kcd debug spels` opened
or closed it. The sub-verb list printer is now a file-local printDebugList:
the bare verb still toggles the console and prints it (debug-logging-§5), and
the unknown-word path refuses and prints it without the toggle.
runDebug now passes the remainder after the sub-verb to the row. A file-local
parseDebugUnit accepts '' / target / focus (any case); castbar calls
Castbar:DebugDump(unit) and interrupt Compat.DebugInterrupt(unit), and any
other word is refused ("unknown unit '<w>', expected target or focus")
through refuse() with no dump. Help strings name the optional unit.
Tests (tests/test_slash.lua): the 'toggle it back' workaround is gone from
the unknown-word case, and a new case pins the console's shown state across
`/kcd debug NoSuch` from both states; four cases cover castbar default /
focus, interrupt focus, and a refused bogus unit. Docs: debug.md,
slash-dispatch.md, testing.md, smoke-tests.md (SLASH list, DIAG-2) and the
README FAQ; docs/test-cases.md regenerated, badge 1316/1316.
Findings: KC-R-03, KC-R-04.
Deviations: the item expected the default `/kcd debug castbar` case to be
green on HEAD; it was red there because HEAD called DebugDump() with nil
(the callee defaulted to target), and the test asserts the explicit unit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoCGDEVoaSdzqSHHsASPMi
commit eaa01c9667698a9d65ee9dfdfb98ca6699c0ff17
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Oct 7 20:18:08 2026 +0530
KC-03: address review — diagnostics prints the any-cast gate, newInstance declares it
Review of 33696cd found two missed ripples of the third gate scalar:
- modules/Diagnostics.lua: the IconGrid section's gate line printed only
lastGateCasting and lastGateInterruptible, so for a friendly caster it
read "gate casting=false interruptible=nil" while the gate had moved on
the raw cast state. It now appends any=<lastGateAnyCasting>.
- modules/IconGrid.lua: newInstance declares lastGateAnyCasting = nil
beside the other two cached gate scalars (no runtime change; the
constructor lists all per-instance state, as docs/icon-grid.md names).
- tests/test_diagnostics.lua: red-first case "the IconGrid gate line names
all three cached gate scalars, the raw cast state included".
- docs/test-cases.md regenerated (Total 1311), README Tests badge 1311/1311.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoCGDEVoaSdzqSHHsASPMi
commit 33696cdfba99661c3f0f51d9bbc3e7338b2f2eca
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Oct 7 20:12:35 2026 +0530
KC-03: glow gate tracks any target cast for the target_casting trigger
The 'target_casting' glow trigger reads inst.isCasting() (any cast by
the unit, the same meaning as the same-named visibility mode), but
IconGrid:RefreshAllGlows keyed its short-circuit gate only on
IsHostileUnitCasting and the interruptibility tri-state. For a friendly
or otherwise non-attackable caster both stayed at (false, nil), so the
per-icon UpdateGlow never ran: the glow did not start on the cast and
went stale when it ended.
Decision: 'target_casting' = any cast, friendly or hostile;
'target_casting_interruptible' stays hostile-only. The trigger is
unchanged and the gate is fixed:
- modules/IconGrid_Visibility.lua: RefreshAllGlows computes a third
scalar, anyCasting = hostileCasting or instanceCasting(inst) (no extra
API read when a hostile cast is already known); gateMoved compares
inst.lastGateAnyCasting too; the cache stores three scalars (still no
table). Doc comments name the three gate inputs and why the raw cast
state is in it. RefreshAllGlows and gateMoved stay under CCN 15.
- defaults/Profile.lua: glow-trigger comment says 'target_casting' is
any cast and 'target_casting_interruptible' hostile only.
- tests/test_icongrid_glowgate.lua: red-first case "a friendly cast
moves the gate for the target_casting trigger" (red on HEAD: the spy
UpdateGlow ran once, not twice) and "an unmoved friendly-cast gate
still short-circuits".
- docs/data-flow.md (glow paragraph) and docs/icon-grid.md describe the
three-scalar gate; docs/test-cases.md regenerated, README badge
1308 -> 1310.
Finding: KC-R-05.
Deviation: docs/icon-grid.md had no glow-gate paragraph to update; the
existing glow-gate prose lives in docs/data-flow.md, which carries the
full description, and icon-grid.md gains a sentence on the cast-filter
paragraph. tests/perf.lua has no glowGate scenario (the bracket is
in-game only), so the perf gate is the offline run passing unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoCGDEVoaSdzqSHHsASPMi
commit 36a880844762145ee026428738c1e3a6f218b30d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Oct 7 20:04:38 2026 +0530
KC-02: count cast-bar name truncation in UTF-8 characters, not bytes
truncateName measured the spell name with #name and cut it with
string.sub under a "Truncate after (characters)" label, so accented
names were cut early, Cyrillic at about half and CJK at about a third of
the promised length, and a cut could split a code point into an invalid
glyph. modules/Castbar.lua gains a file-local utf8Prefix(s, cap) that
mirrors MultiMeters' utf8Truncate (every byte outside 0x80-0xBF starts a
character; return s:sub(1, i-1) at the (cap+1)th start, else s).
truncateName keeps its nil / 0 / secret short-circuits, then appends the
ellipsis only when utf8Prefix actually cut. A name of exactly maxChars
characters is never truncated whatever its byte length. The stale
"byte-counted" header comment is rewritten (characters, no split code
point, pure Lua because strlenutf8 is absent headlessly, never called on
a secret), and docs/castbar.md's truncation sentence now says characters.
No LibKa0s helper (Option B per the verified verdict).
Tests (tests/test_castbar_helpers.lua), red first on HEAD:
- TruncateName('Éclair de givre', 3) == 'Écl…'
- CJK: TruncateName('脚踢打断', 2) == '脚踢…'
- a 4-character Cyrillic name at cap 4 is returned unchanged
- every output, over caps 1..12 on four names, is valid UTF-8
Existing ASCII and secret pass-through cases unchanged and green.
docs/test-cases.md regenerated and README badge moved 1304 -> 1308.
Finding: KC-R-02.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoCGDEVoaSdzqSHHsASPMi
commit 5cd119e3e9bb9ac859ee4f1ccea0a7589c256643
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Oct 7 19:59:54 2026 +0530
KC-01: drop a stale primary-icon anchor when the icon grid empties
Castbar:OnGridLayout cached payload.primaryIcon only when it was non-nil,
but IconGrid announces primaryIcon = nil for an empty grid and releases the
old button to its pool (ClearAllPoints + Hide). The cache kept that orphan,
so ApplyAnchor in PRIMARY mode kept anchoring to it and never reached the
resolveGridFrame fallback. The payload is the full layout announcement, so
primaryIcon is now copied verbatim (nil included); gridFrame keeps its guard
since every announcement carries it. The misleading "defensive" comment is
rewritten, and resolvePrimaryIcon's comment in Castbar.lua now says the
cache can hold nil and the bar then falls through to the grid frame.
Tests (tests/test_castbar_frame.lua), red first on HEAD:
- an empty grid announcement drops the cached primary icon and anchors to
the grid frame (red: cache still held btnA)
- a focus grid announcement never touches the target bar's cache
docs/test-cases.md regenerated and the README Tests badge moved to
1304/1304. Owner smoke check (empty spell list in PRIMARY mode, cast bar
stays visible at the grid) is the owner's to run.
Findings: KC-R-01
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoCGDEVoaSdzqSHHsASPMi
commit e1dabec707024d9cf57b18912b936921a427ec93
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Oct 7 19:52:54 2026 +0530
RV-KC: re-vendor LibKa0s v1.71.0 (kit 38) with v1.69.0-v1.70.0 span
Mechanical re-vendor from the LOCAL LibKa0s tag v1.71.0 (cb274a4):
libs/LibKa0s/ and tests/_kit/ replaced whole from git archive (base
v1.70.0 confirmed against the payload bytes). Minors: WidgetsLineChart 3,
WidgetsAutocomplete 2, Slash 20 / SlashParse 2, Env 2, OptionsIdList 4;
kit revision 37 -> 38 (new secrets.lua, --list Totals exclude declared
skips).
- CLAUDE.md provenance line v1.70.0 -> v1.71.0.
- docs/testing.md: the version-now sentence is de-tagged (it no longer
names the tag ../LibKa0s sits on; it states the two agree only between
a re-vendor and the library's next tag) so it cannot rot (KC-A-01).
- docs/test-cases.md regenerated with --list: Total 1302 now equals the
README badge (1302/1302) and a '| Skipped | 1 |' row carries the
diagnostics opt-out declared skip (KC-A-07). Badge unchanged.
- docs/revendor/2026-10-07-v1.71.0/ (01_DELTA, 02_CANDIDATES,
05_SUMMARY): candidates (Kit.secret + issecretvalue installer,
LineChart clipping/hover, Autocomplete re-hook guard) listed as not
adopted in this run (owner scope ruling 5); no interview, no issue.
- docs/revendor/2026-10-07-v1.69.0-v1.70.0/ (01_DELTA, 05_SUMMARY): span
bundle for the unrecorded re-vendors da8a8b8 (v1.69.0) and 9d4a10b
(v1.70.0), base v1.68.1; Autocomplete noted as a possible Spells
add-box candidate, not adopted, no issue (KC-A-01).
Blocker fixed host-side (mechanical, from kit 38): tests/test_list_mode.lua
pinned revision 37's Totals (Total == every bullet, skips included) and
failed 1302 vs 1303. The case is replaced by one asserting the new
contract no less strictly: Skipped row == bullets marked "(skipped: ...)"
and Total + Skipped == every bullet. No edit under libs/ or tests/_kit/
beyond the copy.
Not committed: test_eol flagged docs/audits/2026-10-07/01_CURRENT_STATE.md
and 02_DEVIATIONS.md as LF on disk (index already correct, pre-existing);
repaired by re-checkout, no content change.
Gate: 1302 passed, 0 failed, 1 skipped; luacheck 0/0 in 127 files;
lizard no function above CCN 15; largest authored .lua 996 lines.
Findings: KC-A-01, KC-A-07.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoCGDEVoaSdzqSHHsASPMi
commit 99136049d7fef7d40047959b794f219dc89199c4
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Oct 7 16:51:55 2026 +0530
RA-00: record 2026-10-07 standards audit and review bundles
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RoCGDEVoaSdzqSHHsASPMi
commit 9d4a10bd3519acee65e0f73e107a2858e62cb018
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Oct 7 11:38:50 2026 +0530
chore: re-vendor LibKa0s v1.70.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L4XiFWzQrd9ee19aBpkVmt
commit 9d4a10bd3519acee65e0f73e107a2858e62cb018
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Oct 7 11:38:50 2026 +0530
chore: re-vendor LibKa0s v1.70.0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L4XiFWzQrd9ee19aBpkVmt
commit da8a8b882a4984893b422e43cfd7e06a7646ce21
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Oct 6 14:52:58 2026 +0530
chore: re-vendor LibKa0s v1.69.0 (kit 37; adds the line chart widget)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L4XiFWzQrd9ee19aBpkVmt
commit 7b29045a6542b39dc64034e1ec0a372d3f35f289
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Oct 4 15:17:12 2026 +0530
DC-REV-01: re-vendor LibKa0s v1.68.1 (kit 36; no library minor moved)
Both payloads copied whole from the pushed annotated tag v1.68.1 (9000cbd, tag object 9fb7956)
via git archive. libs/LibKa0s/ is byte-identical to v1.68.0's: no LibStub minor moves, no file
added or removed, no floor rises. tests/_kit/ moves to kit revision 36 (framework.lua,
run-automated-tests.sh, test_eol.lua): the kit names /dev-copilot:* commands where it named
/wow-addon:*. Nothing was removed upstream, so nothing was deleted. diff -r against the tag is
empty for both payloads, with and without --strip-trailing-cr.
The CLAUDE.md provenance line rolls to v1.68.1 in this commit, and docs/testing.md's version-now
sentence rolls with it. No prose here names the kit revision this repo holds; every remaining
"kit 35" names the revision the sighted complexity suite arrived in, so it stays. No contract
blocker.
Zero adoption candidates (rename-only release), so no interview. Item stays a settled decline
(#14). Frozen bundle: docs/revendor/2026-10-04-v1.68.1/ (01_DELTA, 02_CANDIDATES, 05_SUMMARY).
Tests: 1302 passed / 1 skipped / 1303, unchanged (including both vendor-sync cases).
docs/test-cases.md regenerates identical; the README badge is unchanged.
luacheck: 0 warnings / 0 errors in 127 files.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MsGF7a1YxB69EsRnBC8rcE
commit 7b29045a6542b39dc64034e1ec0a372d3f35f289
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Oct 4 15:17:12 2026 +0530
DC-REV-01: re-vendor LibKa0s v1.68.1 (kit 36; no library minor moved)
Both payloads copied whole from the pushed annotated tag v1.68.1 (9000cbd, tag object 9fb7956)
via git archive. libs/LibKa0s/ is byte-identical to v1.68.0's: no LibStub minor moves, no file
added or removed, no floor rises. tests/_kit/ moves to kit revision 36 (framework.lua,
run-automated-tests.sh, test_eol.lua): the kit names /dev-copilot:* commands where it named
/wow-addon:*. Nothing was removed upstream, so nothing was deleted. diff -r against the tag is
empty for both payloads, with and without --strip-trailing-cr.
The CLAUDE.md provenance line rolls to v1.68.1 in this commit, and docs/testing.md's version-now
sentence rolls with it. No prose here names the kit revision this repo holds; every remaining
"kit 35" names the revision the sighted complexity suite arrived in, so it stays. No contract
blocker.
Zero adoption candidates (rename-only release), so no interview. Item stays a settled decline
(#14). Frozen bundle: docs/revendor/2026-10-04-v1.68.1/ (01_DELTA, 02_CANDIDATES, 05_SUMMARY).
Tests: 1302 passed / 1 skipped / 1303, unchanged (including both vendor-sync cases).
docs/test-cases.md regenerates identical; the README badge is unchanged.
luacheck: 0 warnings / 0 errors in 127 files.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MsGF7a1YxB69EsRnBC8rcE
commit 604797d2324972a25d4b65a2bb0482ca8117df05
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Oct 4 14:21:52 2026 +0530
DC-REN-01: name the dev-copilot commands in live docs
The wow-addon plugin merged into dev-copilot 2.0.0. Live docs and test
comments now name the dev-copilot commands; frozen bundles stay as written.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MsGF7a1YxB69EsRnBC8rcE
commit 604797d2324972a25d4b65a2bb0482ca8117df05
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sun Oct 4 14:21:52 2026 +0530
DC-REN-01: name the dev-copilot commands in live docs
The wow-addon plugin merged into dev-copilot 2.0.0. Live docs and test
comments now name the dev-copilot commands; frozen bundles stay as written.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MsGF7a1YxB69EsRnBC8rcE
commit 0759d7b115a6f8aeffcc76ec23798ccc8e388b3f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Sat Oct 3 12:47:57 2026 +0530
SD-FIN-01: sync docs (Pillow via apt on Ubuntu 24.04; lizard note; drag-handle minor)
pip install Pillow fails under PEP 668, so DEPENDENCIES uses python3-pil; the harness's lizard-sighted case is noted; IconGrid_Handle names the vendored WidgetsDragHandle minor 4.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GBEbct8mwzFqZSG1oTkv8f
commit 961c6525a401da0ed6ff953c29e0e58a72be4450
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Oct 2 23:47:57 2026 +0530
TP-KC-01: both drag strips' tooltips open beside the strip (tooltipPlace)
Adopts LibKa0s WidgetsDragHandle minor 4's tooltipPlace on the cast bar's
and the icon grid's strips. NS.Util.PlaceTooltipBeside (core/Util.lua)
anchors the tooltip TOPLEFT to the strip's TOPRIGHT, or TOPRIGHT to its
TOPLEFT when the strip's right edge plus the tooltip's width would pass the
screen's right edge. The comparison is in screen pixels (each read times its
frame's effective scale; the grid strip takes the master scale). A hovered ?
mark resolves to its strip, so both show the tooltip in one place. Every
read is guarded through NS.Compat.IsSecret plus nil and type checks; on any
untrusted read it answers nil with nothing anchored, so the widget falls
back to the cursor tooltip. It returns true only once placed.
Why adopt when the strips were already frame-owned (ANCHOR_TOP), not
cursor-owned: the owner's request is the tooltip BESIDE the strip, right or
left at the screen edge. ANCHOR_TOP is not that. It opens upward into what
KickCD stacks above the strip (the unit label, and the Focus grid over
Target's by default), it gives the ? mark a second position, and near the
screen top it is clamped back over the strip being hovered. AuraMaster
(TP-AM-01) places its strip tooltips the same way. Reasoning recorded in
docs/revendor/2026-10-02-v1.68.0/03_DECISIONS.md.
Test first: six PlaceTooltipBeside cases in test_util_anchor.lua (right,
left flip, mark -> strip, scaled strip, secret read, nil read) and one
hover case each in test_castbar_frame.lua and test_icongrid_handle.lua
(owned once by UIParent at ANCHOR_NONE, anchored beside the strip). All
eight were red before the code.
Docs: both handle headers, castbar.md, icon-grid.md, module-map.md;
smoke-tests.md gains CAST-15 and GRID-17 (owner-run, unmarked), CAST-10
corrected, routing and owed table updated. Bundle 05_SUMMARY.md.
Gate: 1302 passed / 0 failed / 1 skipped (1303), was 1294 (1295);
docs/test-cases.md regenerated, README badge 1302. luacheck 0/0 in 127
files. Sighted complexity: pass, max CCN 15, 0 warnings
(PlaceTooltipBeside CCN 10). Every file under 1500 lines. No version bump.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7u34U99DrEPHJTMx6E6u8
commit 961c6525a401da0ed6ff953c29e0e58a72be4450
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Oct 2 23:47:57 2026 +0530
TP-KC-01: both drag strips' tooltips open beside the strip (tooltipPlace)
Adopts LibKa0s WidgetsDragHandle minor 4's tooltipPlace on the cast bar's
and the icon grid's strips. NS.Util.PlaceTooltipBeside (core/Util.lua)
anchors the tooltip TOPLEFT to the strip's TOPRIGHT, or TOPRIGHT to its
TOPLEFT when the strip's right edge plus the tooltip's width would pass the
screen's right edge. The comparison is in screen pixels (each read times its
frame's effective scale; the grid strip takes the master scale). A hovered ?
mark resolves to its strip, so both show the tooltip in one place. Every
read is guarded through NS.Compat.IsSecret plus nil and type checks; on any
untrusted read it answers nil with nothing anchored, so the widget falls
back to the cursor tooltip. It returns true only once placed.
Why adopt when the strips were already frame-owned (ANCHOR_TOP), not
cursor-owned: the owner's request is the tooltip BESIDE the strip, right or
left at the screen edge. ANCHOR_TOP is not that. It opens upward into what
KickCD stacks above the strip (the unit label, and the Focus grid over
Target's by default), it gives the ? mark a second position, and near the
screen top it is clamped back over the strip being hovered. AuraMaster
(TP-AM-01) places its strip tooltips the same way. Reasoning recorded in
docs/revendor/2026-10-02-v1.68.0/03_DECISIONS.md.
Test first: six PlaceTooltipBeside cases in test_util_anchor.lua (right,
left flip, mark -> strip, scaled strip, secret read, nil read) and one
hover case each in test_castbar_frame.lua and test_icongrid_handle.lua
(owned once by UIParent at ANCHOR_NONE, anchored beside the strip). All
eight were red before the code.
Docs: both handle headers, castbar.md, icon-grid.md, module-map.md;
smoke-tests.md gains CAST-15 and GRID-17 (owner-run, unmarked), CAST-10
corrected, routing and owed table updated. Bundle 05_SUMMARY.md.
Gate: 1302 passed / 0 failed / 1 skipped (1303), was 1294 (1295);
docs/test-cases.md regenerated, README badge 1302. luacheck 0/0 in 127
files. Sighted complexity: pass, max CCN 15, 0 warnings
(PlaceTooltipBeside CCN 10). Every file under 1500 lines. No version bump.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7u34U99DrEPHJTMx6E6u8
commit 18dc978fea7d59ea58b486df32ccb10c78f1f9ff
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Oct 2 23:42:12 2026 +0530
TP-KC-01: re-vendor LibKa0s v1.68.0 (WidgetsDragHandle 4; kit 35 unchanged)
Whole-folder copy of libs/LibKa0s/ and tests/_kit/ from the local tag v1.68.0
(cc9f5eb, == ../LibKa0s HEAD; git diff --quiet v1.68.0 -- LibKa0s testkit
clean). The one moved file is WidgetsDragHandle.lua, minor 3 -> 4: the
optional tooltipPlace(tip, frame) spec field and descriptor `place`. Without
a hook a hover makes minor 3's calls in minor 3's order, so KickCD's two
strips (cast bar, icon grid) are unchanged by this commit. The kit did not
move (revision 35). No file added or removed; nothing deleted. diff -r of
both folders against the tag is empty; CRLF working tree as before.
Provenance line in CLAUDE.md and docs/testing.md's version-now line roll to
v1.68.0. No blocker (3g: additive only). No span bundle, no base correction.
Frozen bundle: docs/revendor/2026-10-02-v1.68.0/ (01-04; 05 lands with the
adoption commit). Decision recorded there: adopt tooltipPlace on both strips.
Tests: 1294 passed / 0 failed / 1 skipped (1295) before and after, vendor
sync green, so docs/test-cases.md and the README badge are unchanged.
luacheck 0/0 in 127 files. Sighted complexity: pass, max CCN 15, 0 warnings.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7u34U99DrEPHJTMx6E6u8
commit 719e9650df62bbcae754bfc03ac66db7348636b9
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Oct 2 10:24:31 2026 +0530
CA-FIN-02: doc sync before merge
Refresh three stale file:line citations (test_coresetup ls popen, NS.COMMANDS publish, Slash.lua out sink).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7u34U99DrEPHJTMx6E6u8
commit 719e9650df62bbcae754bfc03ac66db7348636b9
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Oct 2 10:24:31 2026 +0530
CA-FIN-02: doc sync before merge
Refresh three stale file:line citations (test_coresetup ls popen, NS.COMMANDS publish, Slash.lua out sink).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7u34U99DrEPHJTMx6E6u8
commit eff6cfcd55bdf3f502aea8517282c773171e9f92
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Oct 2 02:07:21 2026 +0530
CA-KC-02: adopt Core.SECRET; delete PANEL_HEADER_TOP/HEIGHT (KickCD#36 items 4-5)
core/CoreSetup.lua publishes NS.SECRET on both paths: lib.SECRET live, and the
"<secret>" literal in the library-absent arm only, where the stub
NS.SafeToString now returns it too (D3.11, events-frames-taint-§8).
core/Compat.lua's safeRender returns NS.SECRET at call time, so the
`/kcd debug interrupt` dump and every SafeToString line spell one sentinel.
core/Constants.lua deletes PANEL_HEADER_TOP and PANEL_HEADER_HEIGHT, which had
no reader: lib.LAYOUT.HEADER_TOP/HEADER_HEIGHT are INTERNAL to LibKa0s-Options
and never handed to a host, so they are deleted rather than re-read (D3.7). The
PANEL_PADDING_X comment now explains both.
Tests: NS.SECRET equals lib.SECRET live and the stub literal degraded; a
source scan that "<secret>" is spelled only in CoreSetup's library-absent arm;
the two PANEL_HEADER_* cases replaced by a stays-deleted case, and the
restatement lint widened to HEADER_TOP/HEADER_HEIGHT. Docs: module-map,
ARCHITECTURE (cites refreshed), compat-layer, debug, testing, smoke checks
DIAG-45 and DEGRADED-15 with Pending sign-off rows, test-cases.md and the
badge (1294/1294).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7u34U99DrEPHJTMx6E6u8
commit 6cd075e972b8209ac1e3544de85801f1520d39a7
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Oct 2 02:02:36 2026 +0530
CA-KC-02: characterization test for the degraded interrupt dump's <secret>
Pins that with LibKa0s absent, `/kcd debug interrupt` still renders a
secret-tainted name and position as <secret>. Green on today's code, before
KickCD#36 item 4 moves core/Compat.lua's safeRender onto NS.SECRET, which
the library-absent arm of core/CoreSetup.lua must then supply. test-cases.md
and the badge (1292/1292).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7u34U99DrEPHJTMx6E6u8
commit 2353c1a32b33a4ecb46c90059554290fd385a5df
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Oct 2 01:58:06 2026 +0530
CA-KC-01: adopt Slash.SplitVerb, FindCommand and CommandRows (KickCD#36 items 1-3)
settings/Slash.lua publishes NS.Slash.SplitVerb / FindCommand / CommandRows on
both paths: LibKa0s-Slash-1.0's minor-19 members live, and a minimal stub in
the library-absent arm (verb split, guarded lookup, PLAIN `cmd desc` rows, no
FormatRow copy, D3.6). The stub's LandingRows / HelpRows and verb lookup reuse
them.
core/KickCD.lua deletes lowerFirst and findCommand and reads NS.Slash.* at call
time: runDebug's inline verb split, both lookups, and both sub-help loops
(`/kcd debug` and `/kcd spells`, D3.7) now go through the library. Sub-help
rows change hex case only (|cFFFFFF00), matching `/kcd help`.
Tests: the characterization rows tightened to exact bytes, a source-scan guard
that core/KickCD.lua carries no `|cffffff00/kcd`, lowerFirst or findCommand,
the degraded sub-lists pinned to the plain shape, the stub vocabulary's
contract, and the surface-parity case naming the three members. Docs:
slash-dispatch, module-map, ARCHITECTURE, smoke checks SLASH-14 and
DEGRADED-14 with Pending sign-off rows, test-cases.md and the badge
(1291/1291). Two stale settings/Slash.lua line cites in tests refreshed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7u34U99DrEPHJTMx6E6u8
commit ece3a6e43c26819d2b0bf15cebface4e51c4c503
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Oct 2 01:53:00 2026 +0530
CA-KC-01: characterization tests for the /kcd debug and /kcd spells sub-levels
Pins today's sub-help rows (shared-format, table order, case-insensitive hex),
the unknown-debug-word refusal and reprint, case-insensitive sub-verb matching
with the remainder's case kept, and the degraded sub-lists answering. Green on
today's code, before KickCD#36 items 1-3 adopt Slash.SplitVerb, FindCommand
and CommandRows.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7u34U99DrEPHJTMx6E6u8
commit 1777794325acb7645aaef0b7fa258da2a8c82c64
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Oct 2 01:47:41 2026 +0530
CA-KC-NM: the Options descriptor passes addonName (LibKa0s#42)
settings/OptionsSetup.lua keeps its first vararg as `addonName` (was `_`)
and passes `addonName = addonName,` on the Options descriptor beside
parentTitle/mainPanelName, so an IdList help mark draws the library's own
`info` art (Options 28 / OptionsIdList 3) rather than the client glyph.
Latent here: KickCD has no IdList with help today. The library-absent
path is unaffected (the descriptor only gains a string field).
Test first: tests/test_options_panel.lua gains a source-pattern guard
(the vararg is named addonName, and the descriptor table passes
`addonName = addonName,`) plus an on-disk assert that
libs/LibKa0s/media/icons/info.tga is vendored. Red on the old source.
Totals: 1282 passed / 1 skipped / 1283 -> 1283 passed / 1 skipped / 1284.
luacheck 0/0. Vendor parity clean. Sighted complexity green (max CCN 15).
Docs: test-cases.md regenerated, README badge, smoke-tests.md PANEL-30
(index range, OptionsSetup partial-change line, Pending sign-off row).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7u34U99DrEPHJTMx6E6u8
commit 48f79605d8d07ec3d7d2fe81893e7e6e75227469
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Oct 2 01:40:11 2026 +0530
CA-KC-RV: re-vendor LibKa0s v1.67.0 (Core 10, Options 28, OptionsIdList 3; kit 35 unchanged)
Whole-folder copy of libs/LibKa0s/ and tests/_kit/ from the local tag v1.67.0
(0bccf4c, == ../LibKa0s HEAD, clean tree): Core 9 -> 10 (MakeResizable
canResize / onResizeStop / gripParent), Options 27 -> 28 (docblock),
OptionsIdList 2 -> 3 (addonName loaded-addon guard). The kit did not move
(revision 35). No file added or removed; nothing deleted. diff -r of both
folders against the tag is empty; CRLF working tree as the v1.66.0 re-vendor.
Provenance line in CLAUDE.md and docs/testing.md's version-now line roll to
v1.67.0. No consumer test broke from a library change. KickCD passes none of
the new MakeResizable fields (its grips are the library's console, copy
window and perf panel) and builds no IdList; addonName is CA-KC-NM.
Frozen bundle: docs/revendor/2026-10-02-v1.67.0/ (candidates listed, not
interviewed, per the census adoption design).
Tests: 1282 passed / 0 failed / 1 skipped (1283) before and after, so
docs/test-cases.md and the README badge are unchanged. luacheck 0/0 in 127
files. Sighted complexity: pass, max CCN 15, 0 warnings, blindFiles 0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7u34U99DrEPHJTMx6E6u8
commit 499cf1e398c79124751041c341c2f87ed14dca79
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Oct 2 00:40:12 2026 +0530
README: an FAQ row for /kcd perf
/kcd perf was in NS.COMMANDS (and /kcd help) but nowhere in the README. One FAQ row names the
start, finish and report steps and points at bare /kcd perf for the rest.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7u34U99DrEPHJTMx6E6u8
commit 499cf1e398c79124751041c341c2f87ed14dca79
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Oct 2 00:40:12 2026 +0530
README: an FAQ row for /kcd perf
/kcd perf was in NS.COMMANDS (and /kcd help) but nowhere in the README. One FAQ row names the
start, finish and report steps and points at bare /kcd perf for the rest.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7u34U99DrEPHJTMx6E6u8
commit 5657d508061ac2da36b392bbd20d732848b0a4ec
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Oct 2 00:13:29 2026 +0530
GI-FIN-02: record the 2026-10-02 smoke passes; doc sync
GRID-15 and GRID-16 (KickCD#9, the ticker owns time) passed in the owner's 2026-10-02 client run
and leave Pending sign-off. module-map re-measures three peeled files that grew later in the pass
(none back in the band); ARCHITECTURE names IconGrid's five siblings.
Gate: 1282 pass / 0 fail / 1 skip; luacheck 0/0 in 127 files; vendor diff empty.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7u34U99DrEPHJTMx6E6u8
commit 5657d508061ac2da36b392bbd20d732848b0a4ec
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Fri Oct 2 00:13:29 2026 +0530
GI-FIN-02: record the 2026-10-02 smoke passes; doc sync
GRID-15 and GRID-16 (KickCD#9, the ticker owns time) passed in the owner's 2026-10-02 client run
and leave Pending sign-off. module-map re-measures three peeled files that grew later in the pass
(none back in the band); ARCHITECTURE names IconGrid's five siblings.
Gate: 1282 pass / 0 fail / 1 skip; luacheck 0/0 in 127 files; vendor diff empty.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7u34U99DrEPHJTMx6E6u8
commit 1589fb8aee4ee99c919e0a3c66c7fbeeba720d41
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 15:38:14 2026 +0530
GI-KC-12: split the three sighted CCN>15 functions below 15, behaviour identical
The functions the re-vendored kit's sighted complexity suite reports above
CCN 15 (the same set 02a listed at validation time):
Cooldowns.Refresh (modules/Cooldowns.lua) 46 -> 12
newPassLog 5, emitState 3, dropSpell 2, withdrawGcd 5, stampGcd 9,
noteChange 8, logPass 6. The pass log is built only while the console
listens (the old per-pass locals, now one table, still zero-alloc with
debug off); MaterialChange, a pure function, is now called only when its
answer is logged.
IconGrid.Layout (modules/IconGrid.lua) 29 -> 9
layoutSettings 10, bindIcons 2, announceLayout 2, warnTruncation 8.
IconGrid.lua stays out of the layout-§1 band (997 -> 996 lines).
(anonymous)@764 tests/test_perfsetup.lua, the bracket-leak scan 19 -> 2
sourceLines 2, noteGuards 4, opensBracket 3, blockLeaks 6, fileLeaks 7.
Characterization: tests/test_cooldowns_refresh.lua and
tests/test_icongrid_layout_pass.lua (previous GI-KC-12 commit) green before
and after. The leak scan, being a test, was characterized by mutation: two
mutants of Cooldowns:PollSpell's Notes (drop the early-return Note; drop
both) produce byte-identical failure reports before and after the split.
Sighted complexity: 3 warnings (max 46) -> 0 warnings (max 15), blindFiles 0,
bandFiles 0, overCapFiles 0. Totals unchanged: 1282 passed / 1 skipped /
1283 before and after. luacheck 0/0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ng9STmzmM1JYwT2WWSakpL
commit 9787b9e65a40562c57b1db13d8474d3ed6414ed3
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 15:32:49 2026 +0530
GI-KC-12: characterization tests for Cooldowns:Refresh and IconGrid:Layout
Written and run green against the unsplit functions the sighted complexity
gate reports above CCN 15 (Cooldowns.Refresh 46, IconGrid.Layout 29), so the
splits that follow are checked rather than assumed.
tests/test_cooldowns_refresh.lua (10): the two guards, the vanished-spell
sentinel and drop=[] (and that a drop alone keeps the (gcd) marker), the exact
summary line shape and order, the emitted payload, a secret-charges emit with
no line, no GCD attribution written with the console off, the unchanged
record's withdrawal rule, the changed record's stamping in every branch, and
the spellPoll / stateEmit Perf notes.
tests/test_icongrid_layout_pass.lua (9): the no-grid guard, the per-button
binding and its order, every config default and pass-through, the empty-list
size and payload, the laid-out size and payload, the truncation warning's
dedup / re-arm / clear and its ?/? key.
The third function, test_perfsetup's leak-scan case (anonymous, CCN 19), is a
test; its characterization is a mutation run recorded in the refactor commit.
Totals: 1263 passed / 1 skipped / 1264 -> 1282 passed / 1 skipped / 1283.
luacheck 0/0. test-cases.md regenerated, README badge.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ng9STmzmM1JYwT2WWSakpL
commit e0da04c2131e26fa667fec4f6a972fb017ffeb0d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 15:26:37 2026 +0530
GI-KC-11: the Spells list renders through H.RenderGrid with no gap (KickCD#10)
fillRows hands one wide item per entry to H.RenderGrid(ctx, items, scroll,
{ gap = false }) (LibKa0s v1.66.0's parent and opts.gap), instead of its own
scroll:AddChild loop. Each row is built INTO the full-width group the grid
hands make (Spells.BuildRow gains an optional `into`), so that group is the
row: the one child the List layout stacks, ROW_HEIGHT tall, and the frame the
ReorderList controller is handed. reorder:AddRow runs after RenderGrid
returns, because the grid adds the group to the scroll after make. A row that
cannot be built answers false and the grid releases its group. The empty list
is the grid's one item, the guidance label. renderRows keeps its DoLayout.
Tests first: tests/test_settings_spells_grid.lua (5 cases). Red against the
old loop: the RenderGrid call shape, and the empty-list label as the grid's
item. Green pins carried across: one group per entry with no spacer, the
controller's frames in list order at exactly ROW_HEIGHT, an unbuilt row
leaving no blank group. test_settings_spells_editor's rebuildRows helper skips
the guidance's group (one Label child), which no row is.
Totals: 1258 passed / 1 skipped / 1259 -> 1263 passed / 1 skipped / 1264.
luacheck 0/0. Sighted complexity unchanged (3 warnings, blindFiles 0).
Docs: settings-panel.md, module-map.md 20a, smoke-tests.md SPELLS-13,
test-cases.md regenerated, README badge.
Deviation from 02a part B: the row is built into the grid's group rather than
nested inside it, so the registered group's height is set to ROW_HEIGHT by
the builder itself and the editor suite's row indices are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ng9STmzmM1JYwT2WWSakpL
commit 5fa1ec8e68f67332e957000f24d3b02cea47a815
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 15:15:43 2026 +0530
GI-KC-10R: comments describe the KickCD#9 emit contract, not the removed handle re-emit
Review follow-up to ee541b1. Comment-only: the Refresh 'logged' comment, the
refreshWithChurnedHandle section header, and two test comments now say handle
churn produces neither an emit nor a log line (the icon ticker re-fetches the
handle). Suite totals unchanged: 1258/0/1 before and after.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ng9STmzmM1JYwT2WWSakpL
commit ee541b1222412a12676bbf6f04ff1283af8c4b18
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 15:11:17 2026 +0530
GI-KC-10: the ticker owns time-varying icon render; Cooldowns emits only on material change (KickCD#9)
Emit = state changed, ticker = time passed.
- Cooldowns.StateChanged drops the two handle-identity compares and becomes
MaterialChange plus the conservative emit when either charge count is
secret. Cooldowns.RechargeHandle(spellID) publishes the existing recharge
read for the ticker.
- modules/IconGrid_Ticker.lua: the set becomes _cdIcons (icon -> branch);
_RegisterCdIcon / _UnregisterCdIcon / _StopCdTicker replace the text-icon
trio. Icon:StartCooldownTick registers any icon on branch 1 or 2 whatever
showCooldownText says, and paints the first frame with the same call a
tick makes (Icon:_PaintCooldown: body alpha/tint curves on branch 1 only,
GCD-suppression alpha, text). Icon:_TickCooldown re-fetches the handle
each tick (plain isActive + GetSpellCooldownDuration, or
Cooldowns.RechargeHandle). Perf bucket name `cdText` kept.
- Icon:Apply does the state work (branch, swipe arm, first paint, ticker
registration, glow) only on plainStateMoved or force; otherwise only the
charges badge. The swipe is armed only there, never per tick.
- No Lua comparison on any DurationObject getter (landmine test added).
Two additions beyond 02a, both needed once the emit stops carrying a fresh
handle:
- A finished swipe on a still-active spell is re-armed once by the next
tick (OnCooldownDone sets btn._swipeDone). This covers the GCD ->
real-cooldown handoff, where an off-GCD interrupt pressed under a GCD
changes neither isActive nor handle presence, and a recharge rolling onto
the next charge. Without it the swipe would stop at the GCD's end.
- On isActive=false the ticker hides the swipe and text but keeps the icon
registered until Apply takes it to idle, so a recast inside
SPELL_UPDATE_COOLDOWN's lag (Cooldowns sees active -> active, no emit)
re-arms instead of leaving a blank icon. 02a's "unregister" became
"stay registered in an ended state".
Tests first, red against the old code (12 failing): test_cooldowns_gates
(identity no longer emits), test_cooldowns (one emit across polls of an
unchanged cooldown, isActive flip emits, secret charges emit every poll),
test_icongrid_apply (swipe armed only on state work, steady payload touches
only the badge), test_icongrid_render (ticked with text off, no per-tick
re-arm, ended hide, recast re-arm, OnCooldownDone re-arm, branch 2 leaves
the body alone, landmine handle), test_icongrid_curves (GCD -> real CD
dims and tints by ticks alone). Suite 1246/0/1 -> 1258/0/1.
tests/perf.lua: iconApply steady state 848.0 -> 0.0 bytes/iter (ceiling
re-baselined 900 -> 32 with the three-line record); spellState 1696.6 ->
1.5; new cdText scenario asserts 2 API calls per tick.
Docs: midnight-quirks (the forced emit rate is history), data-flow,
module-map, ARCHITECTURE, performance, message-bus, icon-grid, testing,
debug, slash-dispatch, smoke-tests GRID-15/16 + pending rows, test-cases
regenerated, README badge 1258/1258.
luacheck 0/0. Sighted complexity unchanged: 3 warnings, all pre-existing
(Cooldowns.Refresh 46, IconGrid.Layout 29, test_perfsetup anon 19; GI-KC-12).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ng9STmzmM1JYwT2WWSakpL
commit 442dab84b69c9e751fc14549748dd63ed216a840
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 14:50:17 2026 +0530
GI-KC-01R + GI-KC-02R + GI-KC-04R + GI-KC-05R: comments cite the files the peels moved symbols to
shouldBeVisible -> IconGrid_Visibility.lua, ApplyLock -> IconGrid_Handle.lua, the cooldown
ticker -> IconGrid_Ticker.lua (renderer stays in IconGrid_Render.lua), ApplyAnchor ->
Castbar_Frame.lua, the migration ladder -> Database_Migrations.lua; PerfSetup drops a stale
line number. Comment-only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ng9STmzmM1JYwT2WWSakpL
commit 071f93a63d44f08efbc88988c4974b4e8cb3f971
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 14:42:58 2026 +0530
GI-KC-07R: re-point five citations to tests/test_slash_degraded.lua
GI-KC-07 moved the disabled-state and degraded-stub cases out of
tests/test_slash.lua but left five pointers naming the old file:
core/KickCD.lua (enable/disable stay live while disabled; FEATURE_VERBS
vs the live gate), settings/Slash.lua and tests/test_locale.lua (the
stub's DisabledLine library constant), and docs/slash-dispatch.md's
enable/disable row. Comment- and doc-only; suite totals unchanged
(1246 passed, 0 failed, 1 skipped, 1247 total).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ng9STmzmM1JYwT2WWSakpL
commit 63ecea251c98a6a6b26c2729e0653b9c96a1e5a4
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 14:35:59 2026 +0530
GI-KC-RVR: DEPENDENCIES.md names the sighted complexity runner, not raw lizard
The "Am I set up correctly?" block still gave the raw blind
`lizard -l lua -x ...` command as "the `complexity` suite", which
contradicted docs/performance.md:236 and docs/testing.md after GI-KC-RV.
It now gives `bash tests/_kit/run-automated-tests.sh --suite complexity`
(the sighted suite, kit 35). Docs only; suite totals unchanged
(1246 passed, 0 failed, 1 skipped, 1247 total), luacheck 0/0, complexity
verdict green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ng9STmzmM1JYwT2WWSakpL
commit 7bc51bc3f2268b0a9588ab25832e87b4a48589fa
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 14:27:25 2026 +0530
GI-KC-09: split test_perfsetup.lua's suspend/resume and library-absent cases to test_perfsetup_latch.lua (1021 -> 868)
Test-only move, no case added, removed or renamed (KickCD#32).
tests/test_perfsetup_latch.lua (166, 7 cases): the "suspend / resume"
section (the latch as step 0, cast filters disarmed, no re-registration
mid-capture, resume from current state, the session-only suspended flag)
and the "degraded path" section (the probe stub answers every member, the
bracketed paths still run). Every moved case builds its own instance with
T.load and uses none of the suite's helpers. The L-trap case
(docs/testing.md names it here) and firstWatchedSpell with its luacheck
suppression (docs/common-tasks.md cites it) stay in test_perfsetup.lua.
Registered in SUITES directly after test_perfsetup.
docs/test-cases.md regenerated (sorted name list identical). module-map's
band table is now empty: no authored file is in the 1000-1500 band (the
largest is modules/IconGrid.lua at 996).
Suite totals identical: 1246 passed / 0 failed / 1 skipped (1247) before
and after. luacheck 0/0 (123 -> 124 files).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ng9STmzmM1JYwT2WWSakpL
commit 410a61ed38bdeaca574bfc5a36dc2a17bcc11ebf
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 14:24:56 2026 +0530
GI-KC-08: split test_options_panel.lua's degraded-stub and linked-Focus cases to test_options_panel_degraded.lua (1101 -> 742)
Test-only move, no case added, removed or renamed (KickCD#31).
tests/test_options_panel_degraded.lua (371, 9 cases): the "degraded path"
section (the library-absent schema fingerprint, the hollow composers' CLI
reach, the stub's global reset, the stub's no-panel line), the three
linked-Focus cases (no hover highlight, opens General on Units, full strip
inert with only the link note) with their SCHEMA_WIDGET_TYPES local, the
Focus link tick / Copy button row case, and the stub's no-widget-maker
source scan. None reads the suite's shared helpers (renderRow, panelSeq,
the page tables); the degraded cases build their own instances. The L trap
cases stay in test_options_panel.lua (docs/testing.md names it there), as
does the reader / stored-FALSE case ARCHITECTURE.md pins. Registered in
SUITES directly after test_options_panel.
docs/test-cases.md regenerated (sorted name list identical). Every pointer
to a moved case re-pointed: ARCHITECTURE's options-ui-§1 deviation rows,
settings-panel.md, testing.md, slash-dispatch.md, comments in
settings/OptionsSetup.lua, settings/Panel_Render.lua and
tests/test_surface_parity.lua. module-map band table row removed.
Suite totals identical: 1246 passed / 0 failed / 1 skipped (1247) before
and after. luacheck 0/0 (122 -> 123 files).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ng9STmzmM1JYwT2WWSakpL
commit 411eab8f83a1a92def0a2a813ba98dcfacda6742
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 14:21:08 2026 +0530
GI-KC-07: split test_slash.lua's disabled-state and degraded-stub cases to test_slash_degraded.lua (1054 -> 719)
Test-only move, no case added, removed or renamed (KickCD#30).
tests/test_slash_degraded.lua (361, 18 cases): the "disabled state
(slash-commands-§2)" section (disabled(), say(), LIVE and its seven cases)
and the "degraded stub's contract" section (degraded(), degradedRun(),
ABSENT and its eleven cases). Every moved case builds its own instance with
T.load, so none depended on suite order. test_slash.lua keeps its own copy
of the small say() capture helper, which the `/kcd get` bool case and the
`/kcd spells add` cases still use. Registered in tests/run.lua's SUITES
directly after test_slash.
docs/test-cases.md regenerated (the 18 names move between headings; the
sorted name list is identical). docs/slash-dispatch.md's four pins re-pointed
to the new file where their case moved; module-map band table row removed.
Suite totals identical: 1246 passed / 0 failed / 1 skipped (1247) before
and after (test_slash 60 -> 42 + test_slash_degraded 18). luacheck 0/0
(121 -> 122 files).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ng9STmzmM1JYwT2WWSakpL
commit 252fdc034847363fa7882f90522efe3cda038d64
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 14:18:10 2026 +0530
GI-KC-06: peel the Spells page's chrome-block builders to settings/Spells_Header.lua (1115 -> 914)
Pure move, no behaviour change (KickCD#28), mirroring Spells_Rows.lua.
settings/Spells_Header.lua (254): CLASS_DISPLAY_OVERRIDES, titleCaseToken,
classDisplayName, classColorHex, classIconMarkup, the spec-icon cache,
specIconMarkup, buildSpecEntries and buildSpellsHeader, published as
Spells.BuildHeader (renderRows calls it at render time) with the
TitleCaseToken / ClassDisplayName test exports.
The page's file-locals reach it through Spells.__headerDeps, filled at
Spells.lua's file end and read at call time through forwarders (sortedKeys,
specOrder, currentSpellIds, addFromBox, ADD_STRINGS, HEADER_ROW_GAP). The
page's mutable state is not copied: buildSpellsHeader reads the selection
through the existing Spells:GetSelection, writes it through
__headerDeps.setSelection, and appends to the header-widget list
__headerDeps.newHeaderWidgets() creates on the page, which
releaseAceGUITree still releases. Those three lines are the only edits
inside the moved bodies.
KickCD.toc: after Spells_Rows.lua under the LOAD-BEARING note (which now
names both siblings). tests/test_locale.lua's two CLIENT SUPPLIED residue
rows ("Death Knight", "Demon Hunter") follow the literals to the new file
(same rows, same case count).
Docs: module-map (tree, new 20b, band table row removed), ARCHITECTURE
(subsystem table, load order, the spell-list writer note).
Suite totals identical: 1246 passed / 0 failed / 1 skipped (1247) before
and after. luacheck 0/0 (120 -> 121 files).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ng9STmzmM1JYwT2WWSakpL
commit 2dcf7308f982a3c8306395343af85cfb69e22e34
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 14:13:51 2026 +0530
GI-KC-05: peel core/Database.lua's migrations to core/Database_Migrations.lua (1121 -> 758)
Pure move, no behaviour change (KickCD#29).
core/Database_Migrations.lua (394): the "Profile migration" section whole --
LEGACY_TOPLEVEL / foldAnchors / FoldLegacyUnits, BackfillLabelStyle, the
spec-key helpers and MigrateSpecKeys, the color-shape helpers and
MigrateColorShape, MigrateFontFlags, the `migrations` ladder,
reportMigrationFailure and MigrateProfile -- kept together so the runner and
its steps read in one place. They are defined on NS.Database, which
Database.lua creates, so the file sits directly after it in the TOC under a
LOAD-BEARING note. It reads Database.CURRENT_DB_VERSION (already published)
and the deep copy, now published as Database._copy rather than duplicated.
Init and OnProfileChanged still call the migrators as methods at run time.
.luacheckrc: the 212/self entry for MigrateColorShape / MigrateFontFlags
moves from core/Database.lua (which no longer needs it) to the new file.
Docs: module-map (tree, item 8, new 8a, band table row removed),
ARCHITECTURE (subsystem table, load order), debug.md's Init / Migrate tag
homes.
Suite totals identical: 1246 passed / 0 failed / 1 skipped (1247) before
and after. luacheck 0/0 (119 -> 120 files).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ng9STmzmM1JYwT2WWSakpL
commit 5b51f60ed9ecbce9708b6069f795ad40b2680ccb
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 14:10:57 2026 +0530
GI-KC-04: peel Castbar's lock/drag/anchor code and EnsureFrame to Castbar_Frame.lua (1251 -> 949)
Pure move, no behaviour change (KickCD#24, the second peel after
Castbar_Events in 99211f0).
modules/Castbar_Frame.lua (347): dragAllowed, onDragStart, saveAnchor,
onDragStop, SETPOINT_MAP / toSetPoint, Castbar:ApplyAnchor, Castbar:ApplyLock
and Castbar:EnsureFrame, with the DragAllowed / SaveAnchor / ToSetPoint
exports. Helpers come off the module table at load (Cfg, ResolveGridFrame,
IsVisible, and two new exports from Castbar.lua: ResolvePrimaryIcon and
_OnUpdate, the per-frame loop EnsureFrame wraps once per instance; it is
defined by the time this file loads, so the wrapped function is the same).
Castbar.BuildHandle is still read when EnsureFrame runs.
KickCD.toc: directly after Castbar.lua in the LOAD-BEARING block (note now
names all five siblings). test_castbar_skin's existing LOC case lists the new
file (same case, no count change). .luacheckrc gives it the 212/self entry
Castbar.lua has (ApplyAnchor moved with its receiver). Stale comments in
Castbar.lua's header / forward declaration and Castbar_Handle.lua re-pointed.
Docs: module-map (tree, item 15, new 15a, Handle renumbered 15aa, band table
row removed), ARCHITECTURE (drag-stop writer, load order), castbar.md's
SETPOINT_MAP home.
Suite totals identical: 1246 passed / 0 failed / 1 skipped (1247) before
and after. luacheck 0/0 (118 -> 119 files).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ng9STmzmM1JYwT2WWSakpL
commit ec383aa4d2b46f467e63dbff157b9134686fd156
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 14:07:10 2026 +0530
GI-KC-03: peel the mock's frame model to tests/wow_mock_frames.lua (1233 -> 834)
Pure move, no behaviour change (KickCD#27).
tests/wow_mock_frames.lua (418): NUMERIC_GETTERS, recordPoint, the
FRAME_METHODS table and every method on it, createRegion, recordHook,
refuseUnknown and makeFrame. It returns { makeFrame, FRAME_METHODS,
recordHook }; wow_mock.lua loads it with
assert(loadfile(root .. "/tests/wow_mock_frames.lua"))(root), the same
root-relative loadfile-and-call the runner uses for wow_mock.lua itself.
recordHook is exported because build() writes the same HookScript ledger
for the AceGUI widgets it wraps. The C_Timer queue, AceDB and the build()
body stay in wow_mock.lua. Not a suite, so not in SUITES; luacheck covers it
as part of tests/.
Docs: testing.md's mock layout, common-tasks' linted-files list, module-map
band table row removed; one test comment re-pointed.
Suite totals identical: 1246 passed / 0 failed / 1 skipped (1247) before
and after. luacheck 0/0 (117 -> 118 files). tests/perf.lua runs clean.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ng9STmzmM1JYwT2WWSakpL
commit ef899835843bcb76605dd9c9f7aa30b58edb15a5
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 14:03:30 2026 +0530
GI-KC-02: peel IconGrid_Render's cooldown-text ticker to IconGrid_Ticker.lua (1014 -> 859)
Pure move, no behaviour change (KickCD#26). Named IconGrid_Ticker rather
than the issue's IconGrid_Text because KickCD#9 (GI-KC-10) makes it the
ticker that owns an icon's whole time-varying render.
modules/IconGrid_Ticker.lua (182): the _textIcons / _textTicker locals, the
SetFormattedText rationale, Icon:StartCooldownText / StopCooldownText /
_RenderCooldownText (defined on the IconGrid.Icon prototype the render file
publishes; Mixin copies it at widget creation, after load), and the shared
ticker block (_tickAllTextIcons, IconGrid:_RegisterTextIcon /
_StopTextTicker / _UnregisterTextIcon). The cdText Perf bracket moves with it.
KickCD.toc: after IconGrid_Render.lua under the LOAD-BEARING note, and named
in the PerfSetup note. test_perfsetup's three bracketed-file lists name it.
.luacheckrc's 212/self entry for the two text-icon methods moves from
IconGrid_Render.lua (which no longer needs it) to IconGrid_Ticker.lua.
Docs: module-map (tree, items 14 and new 14a, Visibility/Handle renumbered
14b/14c, band table row removed), ARCHITECTURE load order, the mock's
NewTicker comment.
Suite totals identical: 1246 passed / 0 failed / 1 skipped (1247) before
and after. luacheck 0/0 (116 -> 117 files).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ng9STmzmM1JYwT2WWSakpL
commit 04056dfa8a468b6fbc5c8a1bf8099993c917aecd
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 14:00:22 2026 +0530
GI-KC-01: peel IconGrid's visibility gate, glow gate and drag strip (1420 -> 996)
Pure move, no behaviour change (KickCD#25).
modules/IconGrid_Visibility.lua (288): visibilityMode, shouldBeVisible,
ApplyInterruptibilityMask, IconGrid:RefreshVisibility, OnUnitCastEvent,
OnTargetChanged, OnFocusChanged and the glow gate (resolveInterruptible,
gateMoved, logGateChange, RefreshAllGlows), with the VisibilityMode /
ShouldBeVisible test exports.
modules/IconGrid_Handle.lua (200), mirroring Castbar_Handle: handleText,
anchorHandle, buildHandle (published as IconGrid._BuildHandle for EnsureGrid)
and IconGrid:ApplyLock.
IconGrid.lua keeps instanceCasting / isEnabled (exported as before), the
lifecycle, ICON_CAST_ROUTES and onDragStart/onDragStop, and publishes
IconGrid._instances and IconGrid._OnDragStop, which the siblings read at
file load. Both siblings sit in KickCD.toc's LOAD-BEARING block after
IconGrid.lua; Visibility is named in the PerfSetup note and added to
test_perfsetup's three bracketed-file lists (its visibility / castEvent /
glowGate brackets moved with it). .luacheckrc gives both files the same
212/self entry IconGrid.lua has, for the moved methods.
Docs: module-map (tree, item 12, new 14a/14b, band table row removed),
ARCHITECTURE (subsystem table, load order), debug.md tag homes,
midnight-quirks' mask pointer.
Suite totals identical: 1246 passed / 0 failed / 1 skipped (1247) before
and after. luacheck 0/0 (114 -> 116 files).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ng9STmzmM1JYwT2WWSakpL
commit 3901b388ae753b390e93fa5b37a39088838733a0
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 13:54:08 2026 +0530
GI-KC-RV: re-vendor LibKa0s v1.66.0 (kit 35), wire test_lizard_sighted, record sighted complexity
Whole-folder copy of libs/LibKa0s/ and tests/_kit/ from the local tag v1.66.0
(e4c5ef7): SlashParse, WidgetsReorder, PerfSampler and PerfCommands added (the
TOC loads LibKa0s.xml, so no TOC line), kit 34 -> 35 with lizard_sighted.lua and
test_lizard_sighted.lua. diff -r of both folders against the tag is empty.
Provenance line and docs/testing.md's version-now line roll to v1.66.0.
tests/run.lua declares { name='test_lizard_sighted', dir='tests/_kit/' }. The
complexity rows in docs/testing.md and docs/performance.md name the runner's
suite instead of the raw (blind) lizard command; CLAUDE.md's gate line quotes
no lizard. No consumer test broke from a library change.
Sighted parity named one blind file, tests/test_icongrid_curves.lua (three
function literals in a for-in header); hoisted to a local, same case.
Frozen bundles: docs/revendor/2026-10-01-v1.66.0/ (candidates listed, not
interviewed, per spec S4) and the span back-fill 2026-10-01-v1.64.0-v1.65.0/.
Tests: 1238 passed / 0 failed / 1 skipped (1239) before; 1246 / 0 / 1 (1247)
after (+8 kit cases). luacheck 0/0 in 114 files.
Sighted complexity (run-automated-tests.sh --suite complexity): pass,
maxCcn 46, warnings 3 (Cooldowns.Refresh 46, IconGrid.Layout 29,
tests/test_perfsetup.lua:916 anonymous 19; left for GI-KC-12), blindFiles 0
(1 before the hoist), 3374 functions.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ng9STmzmM1JYwT2WWSakpL
commit 5277432433927599f8ef6d10d1cc7701118a6943
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 01:38:25 2026 +0530
DG-KC-01R: the Clear re-arm case drives all four gates, the cast gate and the cast outcome included
The case named four console gates but ran only the list and rebuild ones. It now
runs a secret-flag RefreshAllGlows pass and a Castbar Start/Stop too, and pins
each line once before a Clear, once after, and quiet on the pass after that.
Checked red with each of the two new gates put back on a hand-rolled memo.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 5277432433927599f8ef6d10d1cc7701118a6943
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 01:38:25 2026 +0530
DG-KC-01R: the Clear re-arm case drives all four gates, the cast gate and the cast outcome included
The case named four console gates but ran only the list and rebuild ones. It now
runs a secret-flag RefreshAllGlows pass and a Castbar Start/Stop too, and pins
each line once before a Clear, once after, and quiet on the pass after that.
Checked red with each of the two new gates put back on a hand-rolled memo.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit c8eaa99b130280e2a702b60580e8171a53c539d9
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 01:27:56 2026 +0530
DG-KC-01: adopt: smoke rows for the library's own lines; module map names the sinks
DIAG-41 (a Slash refusal in the console), DIAG-42 (a Lifecycle edge),
DIAG-43 (state lines at the first enable) and DIAG-44 (Clear re-arming the
change gates), in the doc's own shape, with their Pending sign-off row and
the index range. docs/module-map.md's DebugLog, Launcher, Lifecycle and
Slash entries say which sink each descriptor is passed and which lines are
the library's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 1607b93620df96b92220b034c44d4e3afd41cdaa
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 01:23:35 2026 +0530
DG-KC-01: adopt the combat lock's refusal lines on the Grid page's own seams
The Options descriptor already passed `debug`, so the library's combat-lock
refusals (Options minor 27) land as they are. The Grid page's two host
seams that ask the lock, SelectSection and RestoreGridSection, now name
their act (`section <key>`, `defaults grid/<entry>`) instead of the
anonymous `change`. The grid combat case pins both lines, once per act;
docs/debug.md's Cfg rows say what the library writes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit d4e19c2254e48cc7ba169a2d796f791f332a5371
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 01:21:11 2026 +0530
DG-KC-01: adopt the at-enable queue for the dependency and launcher state lines
The Launcher descriptor takes `debugAtEnable` (Launcher minor 5), so
`registered` and a missing broker library land the first time logging is
turned on instead of being gated off at OnEnable. The [Init] summary's
`, missing <names>` clause, the host's workaround for the same gap, is
deleted: LibCustomGlow-1.0 and LibSharedMedia-3.0 are one D.DebugAtEnable
line each, written at load, and the broker pair is the launcher's own line,
so each missing library is named once. Tests pin both landing after the
first enable and not repeating on a second; docs/debug.md follows.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 31180f369987b2ba374a1930088b0a7ab702d769
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 01:14:09 2026 +0530
DG-KC-01: adopt the console's change gates for the list signatures
The four hand-rolled "log on change" gates go through the console's
D.DebugChanged (LibKa0s v1.65.0 DebugLogGates): Cooldowns' rebuild
signature (_lastRebuildSig), IconGrid's per-unit list signature
(lastListSig) and cast-gate label (lastCastLabel), and Castbar's per-unit
cast outcome (lastOutcome). The line is the signature, a unit disabled
forgets its key, and a Clear or a fresh enable re-arms every gate, which
the copies never were. A new flow-trace case pins the re-arm; docs/debug.md
says the gates are the console's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit f320f9a2c96150c047b76b3a83a394ca779871df
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 01:09:06 2026 +0530
DG-KC-01: adopt Slash and Lifecycle debug sinks; drop the host's stand-down lines
The Slash and Lifecycle descriptors take the host's gated sink as `debug`
(LibKa0s v1.65.0: Slash minor 18, Lifecycle minor 3), so the dispatcher's
own refusals land as `[Cmd] refused <verb>: <guard>` and each stand-down /
stand-up edge as one `[Lifecycle]` line naming the hold. core/LifecycleSetup
.lua's logEdge and its `[State]` edge lines are deleted, so an edge is one
line, not two. tests/test_library_lines.lua pins the library's lines landing
in this console, once each, and silent with logging off; docs/debug.md's tag
table and Coverage name the four tags that are the library's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit fa8aeadd286fb5d573910216af93af8552f44fe0
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Thu Oct 1 00:57:04 2026 +0530
DG-KC-01: re-vendor LibKa0s v1.65.0 (kit 34); DebugLog stub gains the gate members
Whole-folder copy of libs/LibKa0s/ and tests/_kit/ from the local tag v1.65.0
(DebugLogGates.lua added; the kit is unchanged at revision 34). The DebugLog
degradation stub answers DebugOnce, DebugChanged, DebugForget and
DebugAtEnable, which the surface-parity case reads off the live instance.
Provenance line, docs/testing.md's checkout note and docs/debug.md's api
link roll to v1.65.0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 8956c0d10ac84fccd3555f14c5a8d32a76101a37
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 30 21:54:20 2026 +0530
DL-KC-05: module-map names the console's 3000-line buffer and its resize grips
core/DebugLogSetup.lua's entry still called the console buffer 1500 lines;
the vendored DebugLog sets lib.MAX_BUFFER = 3000, and since minor 15 the
console and the copy window both carry a session-only resize grip
(Core.MakeResizable). Doc sync only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 8956c0d10ac84fccd3555f14c5a8d32a76101a37
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 30 21:54:20 2026 +0530
DL-KC-05: module-map names the console's 3000-line buffer and its resize grips
core/DebugLogSetup.lua's entry still called the console buffer 1500 lines;
the vendored DebugLog sets lib.MAX_BUFFER = 3000, and since minor 15 the
console and the copy window both carry a session-only resize grip
(Core.MakeResizable). Doc sync only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 7a0cdf3307df37cba004ae47130dcbe764353e7a
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 30 21:19:23 2026 +0530
DL-KC-04: README uses bullets, never numbered lists (standard v2.72.0 documentation-§1)
Usage's four setup steps and Reporting a bug's three steps become '- '
bullets; the setup intro says 'in this order' so the words carry the order
the numbers did. Reporting a bug now matches the v2.72.0 fixed body with /kcd.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 5e740f343892634d06e4ae4fa5f09352fb5f2a96
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 30 20:22:28 2026 +0530
DL-KC-03R: keep README's Reporting a bug section as the standard fixes it (no added sentences)
documentation-§1 item 9: nothing is added to the section. The enable and the
link are stated in docs/debug.md and the smoke rows.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 19d25379e1a18f29b78861c6c6674094d6595afb
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 30 20:16:48 2026 +0530
DL-KC-03R: add DIAG-39 and DIAG-40 to the re-vendor smoke list
The "LibKa0s re-vendor, or a seam file" list in docs/smoke-tests.md now
reads DIAG-16 – 40, so a re-vendor's smoke pass covers the Diagnostics
link and diagnostics turning logging on, both drawn by the library.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit a5989be9f5d7870dc00f7918583d71d506b334af
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 30 20:11:22 2026 +0530
DL-KC-03: re-vendor the final LibKa0s v1.64.0 (kit 34); diagnostics turns logging on for the session
Both payloads copied whole from the local tag v1.64.0: DebugLog 16 -> 17
and DebugLogDiagnostics 1 -> 2, whose RunDiagnostics() calls
SetEnabled(true) before it writes when logging is off (standard v2.71.0,
debug-logging-§14). The console's Diagnostics link runs the same function.
Kit revision 34 rewrites the contract case to "turns it on for the session"
and adds the opt-out case (skipped here: KickCD keeps the default) and the
already-on case. CLAUDE.md provenance stays v1.64.0.
The standards reference needs no stamp: the TOC X-Standard, README badge
and CLAUDE.md follow the standard's versionless templates.
tests/test_diagnostics.lua: the /kcd diagnostics chat case now expects the
seam's "debug logging ON" line ahead of the count line and the flag on
afterwards, and a second run with logging on prints the count line alone.
docs/debug.md says a run (either form or the link) turns logging on for the
session and a /reload turns it off; its DebugLog api citation re-pointed to
version-17.2. README's Reporting a bug, docs/testing.md and
docs/slash-dispatch.md match. docs/smoke-tests.md corrects DIAG-30 (the
header reads Debug: ON after the run) and adds DIAG-39 (the orange
Diagnostics link) and DIAG-40 (diagnostics turns logging on for the
session, /reload turns it off), all under Pending sign-off.
docs/test-cases.md regenerated (1230 cases, 1 skipped); badge 1229/1229.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 0cb364dcef690a7de78c2eacc7681c616bdec420
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 30 17:32:22 2026 +0530
DL-KC-02R: re-point the NS.COMMANDS citation in common-tasks to core/KickCD.lua:374
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit ad887ed3478b2bda8c8fd8dc326f4e5fddc751a0
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 30 17:23:51 2026 +0530
DL-KC-02R: /kcd debug and settings-verb refusals reach the log
The unknown /kcd debug subcommand, the debug topics whose module is
missing, and the list/get/set/profile "settings layer not ready" guards
now log through refuse(), like the sibling reset and lock guards.
docs/debug.md gains a Debug tag row and a coverage row, and lists the
DebugLog-missing refusals (no sink to write to) as deliberately not logged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit dc9f03d35d52724493e0e531db9fe5f84d3f7540
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 30 17:14:37 2026 +0530
DL-KC-02R: a /kcd reset given a retired page word names the redirect
settings/Slash.lua's runReset is host code, so its two redirects (reset
spells, and the five retired page names) are host refusals: one gated [Set]
line names the word. Pinned in the refusal case of tests/test_flow_traces.lua;
docs/debug.md's Set row lists the file.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 5c19b749928bb0c1a93c4101abdbf0106a9e6e02
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 30 17:11:02 2026 +0530
DL-KC-02R: top-level host verb refusals name their guard too
refuse() moves up beside p() and takes a tag, so the host's own top-level
refusals (/kcd lock, unlock, reset, resetall, resetposition with the db or
the settings layer not ready) log one gated [Set] line naming the guard, as
the /kcd spells verbs do on [Spells]. The refusal case in
tests/test_flow_traces.lua pins the lock line; docs/debug.md's Set rows say so.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 6a95be91a6ec63e42e7435497e43c01c526e4775
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 30 17:05:51 2026 +0530
DL-KC-02R: refusals and caught errors reach the log, logEdge keeps its own doc
- core/LifecycleSetup.lua: logEdge and its comment move above eachModule's
docblock, so each function keeps its own comment.
- core/SpellInput.lua: the Cooldown Manager walk keeps each distinct caught
error with its site (GetCooldownViewerCategorySet / ...CooldownInfo), up to
three plus a +N count, and the one build line names them; nothing is kept
with the flag off.
- settings/Panel_Widgets.lua: a link click that raises writes a gated
[Open] line naming the site and the error, beside the chat line; its
literal gets a DIAGNOSTIC residue row in tests/test_locale.lua.
- core/Database.lua: every spell-list writer refusal (add: no spellID,
unknown class, no list; remove/enable/disable/category: not in the list or
no list; move: no list, non-number index, out of range, same position;
reset: no list) logs one gated [Spells] line naming the guard, shared by
the Spells page and /kcd spells.
- core/KickCD.lua: /kcd spells refusals the verb owns (parse, usage, no
list, unknown category or subcommand, class/spec unresolved, db not
ready) log one gated [Spells] line through refuse().
- tests: the CM walk case asserts the site and message; new cases for the
link-click error and the refusal lines; the "writes nothing traces
nothing" case now pins one refusal line per refused verb. Inventory and
badge 1226 -> 1228; docs/debug.md tag table and Coverage updated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 252c38cbffcb513e66a11bb44aa300f5ac2bb16a
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 30 16:43:43 2026 +0530
DL-KC-02: debug coverage audit and fill (debug-logging-§8 diagnosis, §9 quiet steady state)
Fill the gaps the 060 audit found against debug-logging v2.70.0:
- [State] stand-down (naming the holds) and stand-up edges, from the
latch's standDown/standUp (core/LifecycleSetup.lua).
- [IconGrid]/[Castbar] per-unit enable and disable edges.
- [IconGrid] one change-gated list summary per unit per rebuild: drawn,
not-castable and duplicate IDs, or why no list was read. Replaces the
per-duplicate line (debug-logging-§9).
- [Castbar] the cast outcome, change-gated per unit: shown, suppressed by
the visibility mode, or skipped for no duration object.
- [Cooldowns] a rebuild that watched nothing says why, change-gated on
the rebuild signature.
- [Open] a settings open refused in combat or with no options layer.
- [Spells] the cooldown-manager set's build line (size, viewer calls that
raised) and an add the cooldown-manager gate refused; two Spells lines
now pass their arguments to the sink instead of pre-formatting.
- [Init] names an optional library that did not load.
Tests pin each line with a red-under comment, plus quiet-steady-state
cases for the list summary, the cast outcome, the rebuild skip and
Cooldowns:Refresh. docs/debug.md gains a Coverage section; the tag
table, test inventory and badge follow (1216 -> 1226).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit ffe7a1a80a17a75744fd7692cfb86cc8c31a3f81
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 30 16:07:51 2026 +0530
DL-KC-01: re-vendor LibKa0s v1.64.0 (kit revision 33), resize smoke checks
Copies libs/LibKa0s/ and tests/_kit/ whole from the local tag v1.64.0
(Core 9 MakeResizable, DebugLog 15.1, Widgets 11.3, PerfPanel 6; the kit
gains mock_resize.lua) and rolls the CLAUDE.md provenance line and the
testing.md vendor-state stamp with it. The three-place standards reference
carries no version, so v2.70.0 needs no edit there. No test fallout: no
by-name Core parity stub, no host assertion on the resize surface.
docs/smoke-tests.md gains DIAG-34 - 38 (console resize, session-only size,
two consoles independent, copy window, perf panel width only), listed in
the index, the partial-change lists and Pending sign-off.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit f69d967bf5c31030eeca1c149a968f9ad1b9d24f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 30 08:52:12 2026 +0530
SP-FIN-01: re-vendor the test kit at revision 32 (LibKa0s v1.63.0, re-cut)
LibKa0s folded kit revision 32 into the unpublished v1.63.0: tests/_kit/README.md now counts eleven
consumers and thirteen copies, and Kit.VERSION is 32. Prose and the revision integer only; no code,
case or mock changes. tests/_kit/ is byte-identical to the tag again (diff -r empty), so the
vendor-sync case stays green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit f69d967bf5c31030eeca1c149a968f9ad1b9d24f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 30 08:52:12 2026 +0530
SP-FIN-01: re-vendor the test kit at revision 32 (LibKa0s v1.63.0, re-cut)
LibKa0s folded kit revision 32 into the unpublished v1.63.0: tests/_kit/README.md now counts eleven
consumers and thirteen copies, and Kit.VERSION is 32. Prose and the revision integer only; no code,
case or mock changes. tests/_kit/ is byte-identical to the tag again (diff -r empty), so the
vendor-sync case stays green.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 2312d755af6d430ad6f456b04b7078e13931b0d9
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 30 08:12:15 2026 +0530
SP-FIN-01: point the text-icon comment at IconGrid:_RegisterTextIcon, the ticker's real starter
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 17ed9ce5827cea4a201d7b69c296f478be607500
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Wed Sep 30 01:40:18 2026 +0530
SP-FIN-01: sync docs (four-page panel, debug sub-verbs, settings load order, git gate evidence)
Content sync after the smoke-and-profile branch; no structure changed.
- ARCHITECTURE.md: the settings panel is four pages (General, Grid, Spells,
Profiles), not six; the settings module-map row names Grid.lua and
Spells_Rows.lua; thirty-six files write `local _, NS = ...` (44 loaded,
8 read the folder name), not thirty-three; the /kcd debug sub-verb list
gains `diagnostics` in table order and says the bare verb also prints
the list; load order names LibKa0s and AceGUI-3.0-SharedMediaWidgets in
libs/, opens the settings block with SchemaSetup.lua, and lists Grid.lua
and Spells_Rows.lua in TOC order.
- settings-panel.md, slash-dispatch.md: "six pages" -> four, Defaults
button on General / Grid / Spells.
- module-map.md: libs/ load-order row names every vendored library;
tests/test_slash.lua re-measured at 1054 lines (was 1035) in the
1000-1500 band table.
- DEPENDENCIES.md: git is needed inside the green gate itself (three
suites read `git ls-files`), and test_doc_structure.lua also shells to ls.
Gate: 1216 passed / 0 failed; luacheck 0/0 in 113 files. Test count
unchanged, so docs/test-cases.md and the README badge are untouched.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 28fe6a95be73b53d99b543397cc77714bf3f12a0
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 29 23:54:07 2026 +0530
SP-KC-03R: restore the per-page Defaults scope check, fix STATE-15's title
Old §12 L362 said each panel's Defaults (General / Icons / Cast bar) resets
only that panel, leaving the others and the spell list untouched. PANEL-17
covers the Cast bar entry only; PANEL-29 restores the General and Icons
halves, with echoes checked against the rows' fmt, and is listed under
Pending sign-off. STATE-15's bold now closes after "(the default)".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 6c57b0f5e599cfed6ffa6a25871307db1815faed
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 29 23:33:41 2026 +0530
SP-KC-03R: set Free before the DEGRADED rename, restore the em-dash separator wording
DEGRADED-12 needs the Target cast bar in Free mode, but the degraded /kcd set
writes only enabled and locked and the panel does not open, so the anchor mode
must be set before libs/LibKa0s is renamed. DEGRADED-5 again says "no em-dash
separator": seven COMMANDS descriptions carry their own em dash.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 1f8c55c86ae5393d7cf4e3ad4b3860ceab69cd58
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 29 23:16:25 2026 +0530
SP-KC-03R: match COMBAT-3 to the combat cover, make COMBAT-5 reachable
COMBAT-3 expected each sidebar page to print the library's refusal and close
the Settings window; since Options minor 22 a page shown in combat is covered,
the window stays open, and the gray locked notice prints once per combat.
COMBAT-5 asked for a click on the linked note in combat, which the cover
blocks; it now checks that the cover takes the click and nothing opens.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 465ab582b803d32350e8df0ad9dbe542e1c62db2
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 29 23:01:27 2026 +0530
SP-KC-03R: list DIAG-28 and DIAG-30's unrun halves under Pending sign-off
The 2026-09-26 diagnostics run recorded only part of each: KC-S2 and KC-S4
cover DIAG-28's kept trace and clean Copy, KC-S5 covers DIAG-30's full
report and Debug: OFF header. The console opening, the chat count line,
the agreeing counts and the untraced target change have no result, so both
checks move off the signed list and get rows for their unrun halves.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 27512ec591c51ef050ec9fc6f9203b9cdeb47c17
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 29 22:49:38 2026 +0530
SP-KC-03R: sign the X1.4 minimap pass, unlock before FOCUS-2's enable
The 2026-09-25 collection-wide minimap re-run (2026-09-23 plan, X1.4)
passed left-click opening settings, right-click opening the options menu
and the status tooltip in every addon. INSTALL-11 is now signed, and
INSTALL-12 and STATE-9 are listed for their unrun halves only.
FOCUS-2 now unlocks before enabling Focus: a locked cast bar hides
whenever no cast is live, so the bar only shows as its placeholder.
FOCUS-3 locks again, since unlocked bypasses visibility.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 6c8387181fe4ab4db27d96b48d4ca2d31f4041cb
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 29 22:33:47 2026 +0530
SP-KC-03R: re-verify smoke strings, apply the Pending policy, restore three halves
The review of the smoke rewrite found three halves of old checks lost, two
coverage-map gaps and a broken PANEL-18 sentence. Spec S4's clarified
Pending sign-off rule also applies to the whole doc now.
- SLASH-10 drags a Free Target cast bar before /kcd resetall and checks it
comes back to its default anchor (CENTER/CENTER, y = +120) once Free is
set again (old section 12).
- PROFILE-3 checks the character, realm and class entries AceDBOptions
offers, each through KickCDDB.profileKeys (old section 13).
- LABEL-12 also runs Always mode with the label attached to the cast bar:
it follows the grid, not the bar's own hiding (old section 22).
- PANEL-18's note on the ASCII arrow is its own sentence.
Every expected chat and console string was re-read against the code and
the vendored LibKa0s, and these were wrong: /kcd get and set echo a
row's fmt ("50 px", "12 px", "64 px") and a color as {r, g, b, a};
scale has no fmt ("scale = 2"); a color component above 1 switches to
the 0-255 scale rather than clamping; the gate hint shares the "allowed
values:" line; "reset spells" has moved rather than gone; the overflow
warning's text, one per unit, re-armed once the grid fits; primarySize
runs 24-96; the cast bar strip's tooltip is titled "KickCD castbar";
only the slash echo reads "45 deg"; the full combat refusal line; the
debug spells and castbar dumps, the debug ack, the [Cast] [target] gate
line and its "none (no hostile cast)" stop, the drag list's own trace
lines, "Debug: ON/OFF", and the perf start line's timestamp label.
Pending sign-off now lists every carried-over check with no recorded
owner pass, the new checks, and every corrected check (211 of 225). Only
checks the 2026-09-26 Grid page and diagnostics runs passed whole stay
off it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 175490f7b9a5d10ceddb1cfa91da5f4fc71f6a2c
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 29 21:56:52 2026 +0530
SP-KC-03R: restore the smoke coverage the review found lost
The review of SP-KC-03 found six places where the rewrite dropped or
blurred an old check:
- Relinking Focus mid-cooldown (old 20d) had no home; FOCUS-11 runs with
no cooldown and no per-unit tint. New FOCUS-19 re-ticks the link while
the cooldown runs and expects Target's dim red, and carries 20d's
cleanup.
- The Unit-picker check after a mid-cooldown slash write now sits in
FOCUS-17's own steps and result; PANEL-13 no longer points ahead to it.
- COMBAT-10 sets visibility target_casting_interruptible first, the mode
that drives the interruptible-alpha gate on a secret notInterruptible.
- FOCUS-13 starts from /kcd resetall and moves three Target rows, so the
[Set] copy line's N is a checkable 4 (the rows changed plus the link).
- "Which checks to run" re-derived from the coverage map: COMBAT-6 for a
re-vendor, CAST-8 and SLASH-4 for target and focus, DIAG-28 for the
printer and the debug console, and the full reset set for a new schema
row, so no entry runs fewer checks than the old list.
- docs/debug.md cites DIAG-17 and GRID-14 alongside the other old
section 35 checks, wrapped to the file's width.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 89f8ff3d5f0d0a5a417334bb1af9c0cbc66b3931
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 29 21:39:02 2026 +0530
SP-KC-03R: fix the review's smoke-doc defects
The independent review found checks that could pass without exercising
their behavior, and run guidance narrower than the old doc's.
- Pending sign-off holds only unsigned checks carried over; the new
PROFILE-9 - 14, DEGRADED-10 and CAST-14 rows are gone, and DEGRADED-6
joins it for the unrun section-31 notice-before-the-dump half.
- STATE-4 and FOCUS-2 turn Focus off first (it defaults on), so enabling
it while disabled, or building it live, is actually observed.
- PROFILE-2 copies into a scratch profile, so Default keeps 64 and
PROFILE-10's /kcd profile switch visibly shrinks the grid to 40.
- LABEL-15 restores the old section-22 stress run (rapid attach switching,
slider drags, visibility changes).
- "Which checks to run" carries every old subset entry's coverage,
including the re-vendor, hot-path, debug console, perf and media seams.
- STATE-7 drops the reload persistence INSTALL-5 and CAST-8 already check.
- LABEL-11 names Attach to castbar for its first pass; SLASH-3's sentence
reads; PANEL-18 quotes the vendored tooltip's ASCII "->".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit f926e44221f3ffd7323a8649e1b445e752e402ce
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 29 21:15:29 2026 +0530
SP-KC-03: rewrite smoke tests as one evergreen, theme-grouped suite
The old docs/smoke-tests.md had grown to 1165 lines of numbered sections,
batch sign-offs and regression history, with the same behaviors checked in
several places (master enable, lock and drag, resets, profiles, the degraded
install, the console chrome) and some checks gone stale (a six-page settings
tree, a hardcoded compose minor, a degraded settings panel that no longer
exists). Spec S4 of the 2026-09-29 smoke rework asks for one deduplicated
suite grouped by theme with stable IDs.
The new doc is 798 lines and 223 checks in 14 themes (INSTALL, SLASH, PANEL,
PROFILE, STATE, COMBAT, GRID, CAST, FOCUS, LABEL, SPELLS, DIAG, DEGRADED,
LOC), each check one behavior with a Result line. Every old check maps to a
new ID; two are dropped because what they checked no longer exists (the
per-row pcall in Helpers.RenderRows; the settings panel opening without
LibKa0s). New: PROFILE-9 to 14 and DEGRADED-10 for /kcd profile, and CAST-14
for empowered casts, which docs/midnight-quirks.md pointed at as a
nonexistent "smoke C-03 step 4". The NOT YET RUN §31 and §32 checks and the
new ones sit under Pending sign-off.
Inbound references move to the new IDs (testing.md, debug.md,
midnight-quirks.md). DIAG-26 now says "one L" rather than quoting the
pre-respell perf strings, so the smoke doc's prose waiver goes and
common-tasks.md's waiver paragraph says so.
Gate: 1216 passed / 0 failed; luacheck 0/0 in 113 files.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 4907695436969db307181af98a4a5983acce79f5
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 29 20:42:34 2026 +0530
SP-KC-02R: split loadInstance's afterFile loop into loadTocFiles (CCN 19 -> 13)
c2d5852 inlined the afterFile hook loop, its fired-set check and error
branch into tests/run.lua loadInstance, taking it from CCN 12 to 19. The
TOC load plus afterFile handling now lives in a local loadTocFiles helper
(CCN 7); loadInstance is CCN 13. Behavior unchanged: same load order, same
hook timing, same "is not a TOC file" raise. Re-point the shifted
tests/run.lua citation in tests/test_source_style.lua (99-108 -> 117-126).
Gate: 1216/1216 tests, luacheck 0/0, lizard -C 15 (libs/, tests/_kit/
excluded) 0 warnings.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit a5175b8a86e3450fde3eeb6e5d71b7293b57d205
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 29 20:25:37 2026 +0530
SP-KC-02R: re-disable before every live verb in the DISABLED dispatch case
The review found that the typed LIVE list's `profile` entry pinned nothing.
The case "every reserved verb still answers" disabled the addon once and then
dispatched the list in order. `enable` turns the addon back on, and `resetall`
restores the default `enabled = true`, so every verb after `resetall`, which
means `spells` and `profile`, went to an ENABLED addon. Dropping either verb
from NS.EXTRA_LIVE_VERBS left every test_disabled.lua case green. That
contradicts spec S3 step 4, slash-commands-§7 step 7 (each live verb
dispatched while disabled) and testing-§12 (a pin that cannot go red is not
a pin).
The loop now calls setEnabled(inst, false) before each verb and asserts
NS.MasterEnabled() is false before dispatching. The bare-/kcd check at the
end is re-disabled the same way. Mutation-checked in a scratch copy: with
`profile` dropped from NS.EXTRA_LIVE_VERBS the case goes red on
"`/kcd profile` refused", and with `spells` dropped it goes red on
"`/kcd spells` refused". The test count is unchanged (1216), so
docs/test-cases.md and the badge stay as they are. No file:line citation
points into the lines that moved.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit c2d58525a68acef74abd66a69e30f37bbb4a46f3
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 29 13:07:02 2026 +0530
SP-KC-02R: pin the profile row's NS.L read; re-point shifted citations
The review found two defects in SP-KC-02.
The `profile` locale case named "an English literal in COMMANDS" as its
red-under mutation, but enUS's L returns the key, so a literal and the
lookup are the same string on a stock load and the case stayed green
(testing-§12). The runner's instance factory gains an `afterFile` option
that runs a hook on NS right after a named TOC file loads; the case uses
it to give the key a non-identity string after locales/enUS.lua and
asserts the COMMANDS row carries it. Verified: the literal mutation now
fails the case (1215/1). A key that names no TOC file raises, so a typo
cannot leave the hook silently unfired.
.luacheckrc cited SlashLib:New(d) at settings/Slash.lua:322; the
re-vendor commit's added comment line moved it to 323. The run.lua edit
also moved the mocks._G block that tests/test_source_style.lua cites
(it was already stale at 83-97); now 99-108.
Test count unchanged at 1216; docs/test-cases.md matches --list.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 0a25afa2e8215f23db599cca42942c664efe0c51
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 29 12:52:25 2026 +0530
SP-KC-02: /kcd profile via CliProfile
Adds the `profile` host verb (owner decisions D1-D3, spec S3). The behavior
is LibKa0s-Slash-1.0 minor 17's CliProfile: bare lists the stored profiles
with the current one marked; `profile <name>` switches to an existing profile
only, with quotes stripped and case and inner spaces kept; an unknown name is
refused with a did-you-mean and the list and never created; a switch in combat
is refused. KickCD supplies the COMMANDS row (after resetall, NS.L
description) and the descriptor's `profiles = function() return NS.db end`.
`profile` joins NS.EXTRA_LIVE_VERBS beside `spells`: it is a host verb the
library leaves off LIVE_VERBS, and a switch is a repair a disabled addon must
still answer. It stays off NS.FEATURE_VERBS, so the degraded stub does not
refuse it either (the stub's CliProfile prints the library-absent line). A CLI
switch fires AceDB's OnProfileChanged, so Database:OnProfileChanged logs the
one [Profile] line and rebuilds as for a Profiles-page switch.
Tests first: new suite tests/test_slash_profile.lua (14 cases: pinned COMMANDS
order and count, locale key, help row, list, switch plus handler trace and
bus message, quotes and spaces, unknown creates nothing, did-you-mean, already
current, combat, live-verb membership, disabled switch, degraded, degraded
while disabled); the typed LIVE lists in test_slash and test_disabled gain
`profile`.
Docs: ARCHITECTURE slash table gains `profile` (and the missing
`diagnostics` row) and the verb count moves 18 -> 19; slash-dispatch.md's
command table and live-set judgment; profiles.md "Switching from the command
line"; testing.md coverage bullet; README FAQ row. Citations re-pointed:
.luacheckrc core/KickCD.lua:451 -> :468, common-tasks.md NS.COMMANDS
core/KickCD.lua:199 -> :359. docs/test-cases.md and the README badge move to
1216.
Gate: 1216 passed / 0 failed; luacheck 0/0 in 113 files; lizard 0 over CCN 15.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
commit 0710ce8b981894f72b80dfcf418f170b0decdc30
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date: Tue Sep 29 12:32:13 2026 +0530
SP-KC-02: re-vendor LibKa0s v1.63.0
LibKa0s payload from the local v1.63.0 tag (dd7a774): Slash 16 -> 17, the
shared profile verb (profiles descriptor field, CliProfile, ProfileSwitch,
ProfileNames, nine PROFILE_* strings). Every other file is unchanged and the
test kit stays at revision 31. Both payloads copied whole; content diffs empty
after the copy, nothing deleted.
The copy alone turned the kit's by-name Slash surface-parity case red: the
live instance now carries CliProfile and ProfileSwitch and the degraded stub
did not. The stub in settings/Slash.lua gains both on route (b), printing the
library-absent line for /kcd profile and switching nothing, with a new
tests/test_slash.lua case pinning it. docs/slash-dispatch.md names them in the
degraded-verbs list.
CLAUDE.md provenance and docs/testing.md's version-now line roll to v1.63.0;
docs/test-cases.md and the README Tests badge move to 1202. Bundle:
docs/revendor/2026-09-29-v1.63.0/ (only the Slash minor 17 profile surface is
adopted, by this item's next commit).
Gate: 1202 passed / 0 failed; luacheck 0/0 in 112 files; lizard 0 over CCN 15.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R83GGMfYm2GoXLBwdCsbUH
This mod has no additional files

