promotional bannermobile promotional banner

Quick Comms (Retail)

Context-aware quick callouts on a Comms Pad and a ping-wheel-style Comms Dial
Back to Files

1.0.0-release

File nameQuickComms-1.0.0-release.zip
Uploaded
Oct 26, 2026
Downloads
6
Size
12.8 MB
Flavors
Retail
File ID
9330494
Type
R
Release
Supported game versions
  • 12.1.5

What's new

commit 6fcb1abd718aa60d4a977302c73f5adf313b1071
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Mon Oct 26 11:47:07 2026 +0530

    Release v1.0.0

    The first release. The TOC, NS.version and the version tests move from
    0.1.0 to 1.0.0, and the docs and comments that described the shipping
    release follow. The README's unreleased 0.1.0 Version History row becomes
    a shorter 1.0.0 row dated 2026-10-26. DEPENDENCIES.md no longer calls the
    logo a placeholder.

    Release gate: run 20261026-113818 at cdfb373, all four suites green, 0
    functions above CCN 15, blindFiles 0, crashedFiles 0. Preview and test-mode
    data confirmed current by the owner (ANALYSIS.md).

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

commit cdfb373e003f92c84e9a88935b609b090cbccd04
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Mon Oct 26 11:34:40 2026 +0530

    Add the README screenshots; drop the placeholder-logo limitation

    The Screenshots section links the five CurseForge images: Comms pad, Comms
    dial, Group editor, Group situations and Callout editor. The logo is final,
    so known-limitations no longer calls it a placeholder.

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

commit fc088e16b843551d5f96b515ce922859e8f785cf
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 22:07:54 2026 +0530

    Record the 2026-10-25 automated-test run at a3afba3: green

    Lint 0/0 over 140 files, 1176 passed with 1 declared skip, six perf
    scenarios unchanged, no function above CCN 15. The tree was dirty with the
    staged perf bundles, which no suite reads.

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

commit 4b659793ea3264e2b407fdff015b9aee9d27b694
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 22:07:52 2026 +0530

    Record the first two in-game perf captures (2026-10-25)

    20261025-212400: nothing pressed, so no bucket fired; the +1.45 ms/frame
    delta is between two different fights. 20261025-213356: pad and dial
    presses in arm A; dialRender, sendClick and echoMatch cost 0.123 ms per
    second of combat in all, about 0.3% of the +0.61 ms/frame delta. The
    store's README indexes both, and docs/performance.md summarizes them.

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

commit a3afba3b080f32655505803345aad5a7b71e9583
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 21:19:04 2026 +0530

    Add the project-page screenshots; keep them out of the package

    Five screenshots under media/screenshots/ (1.4 MB). .pkgmeta ignores the
    folder, as the other Ka0s addons do, so players never download them, and
    the harness pins that ignore line.

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

commit ab80dac3d3ec4166e2b1e0182ecbf1ce92d5efde
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 21:09:10 2026 +0530

    Put media/textures into a folder per skin

    The dial's own art (disc, ring ladder, sectors) moves to
    media/textures/dial/, and each shine look's art to
    media/textures/shine/<look>/: its pad file, its whole-disc dial file and the
    sprites or edge set it draws (Frosted glass's streaks, Bevel's edges, Glass
    orb's bead, Fluid glass's blooms). The rim edge set that six looks draw
    goes to shine/shared/ rather than six copies. Files keep their names.
    Shine.Folder and the generators' folder() share one rule; the dial reads
    DialSlices.MEDIA. A new test pins every path to its folder and nothing
    loose at the top; ART-2 is the in-game check.

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

commit 1cbb7842a02db7aada138af75c9467c5a2ee337e
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 20:33:15 2026 +0530

    Simplify the README and add a Screenshots placeholder

    The description is two short paragraphs and Usage is four paragraphs plus
    the configuration line (documentation-§1 aims for five or fewer), in the
    order a player meets the addon: the pad, the dial, your own callouts, the
    preview. The detail they dropped (every dial tab, every pad tab, the
    preview's edge cases) stays in docs/settings-panel.md. A Screenshots section
    with four captioned placeholders sits after the description, and the
    0.1.0 Version History row is cut to eight highlights. De-AI pass run on
    the edit.

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

commit 97f8aba99f407b4928f8617b2ebb90bb9eab774b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 20:25:27 2026 +0530

    Publish the CurseForge project id, 1765410

    The TOC carries ## X-Curse-Project-ID: 1765410 in the field's place after
    X-Standard, as every published Ka0s addon does, in place of the unpublished
    comment (toc-file-§1). The harness pins the id, and the README gains the
    CurseForge version badge the other addons carry.

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

commit 848492a1baa49b7f7c6c8a117604ac1e476c5e6c
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 20:21:06 2026 +0530

    Record the in-game pass of the fix run; accept the dial's full-screen catcher

    The owner ran the ten checks the review and audit fixes added or rewrote
    (SEND-6, SEND-7, PAD-16, PAD-17, DIAL-42, DIAL-43, SHINE-4, DEGRADED-2,
    EDIT-34, LAYER-5) and they passed. The owner also ruled the key-opened
    dial's full-screen catcher allowed (audit QC-30): it moves out of the
    frame-layering row into a ratified frame-layering-§4 row of its own,
    re-checked when the standard rules on catchers behind a secure HUD popup.

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

commit 0a50855957c5b0aae7a31d8e2d81333839a99e5e
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 20:10:02 2026 +0530

    Record the 2026-10-25 automated-test run: green, no function above CCN 15

    Bundle 20261025-200510 at aacdc1d: lint 0/0 over 140 files, 1175 passed
    with 1 declared skip, six perf scenarios under their ceilings, complexity
    sighted with 0 warnings (19 before this branch) and seven files in the
    1000-1500 band, each given a disposition. The plan's checkpoints 4-6 are
    done; issue #11 is closed as not planned.

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

commit 0a50855957c5b0aae7a31d8e2d81333839a99e5e
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 20:10:02 2026 +0530

    Record the 2026-10-25 automated-test run: green, no function above CCN 15

    Bundle 20261025-200510 at aacdc1d: lint 0/0 over 140 files, 1175 passed
    with 1 declared skip, six perf scenarios under their ceilings, complexity
    sighted with 0 warnings (19 before this branch) and seven files in the
    1000-1500 band, each given a disposition. The plan's checkpoints 4-6 are
    done; issue #11 is closed as not planned.

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

commit aacdc1deb7963dceba529af13151b0f531dc2103
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 20:00:15 2026 +0530

    Say where the gate time is recorded; credit the QC-R6 widening correctly

    RESULTS.md has no duration column: each bundle's manifest.json carries
    durationMs. The frame-layering row's Decided cell put the dial catcher
    next to the modal-clamping commit; it names both commits now, and the
    re-check trigger says the upstream question is not yet filed.

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

commit 920bd5efefbcc8baa893493c9086754e2f9446c4
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 20:00:14 2026 +0530

    Pin the shine resize, the one lift timer, the key's late re-read and the logo ignores

    Verification found four guards no case turned red under: the pad shine
    case resized through pad.button.width, which moves the look's signature
    too, so a look-only guard still passed; >= 1 on __fireTimers let every
    ENCOUNTER_END arm its own timer; nothing checked that a key's end arms
    the late re-read; and no case read .pkgmeta's media/logos ignores. Each
    now fails under its mutant. The inventory and badge follow (1175).

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

commit b71f1153300793a274a511cfd2c50011d785f9fc
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 19:42:13 2026 +0530

    Tick the plan's checkpoints for the tracks, integration and track E

    Rows 1 to 3 of the checkpoint table record the four track heads, the
    four merges and track E's commits, so a resume starts at verify.

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

commit d9e8e0a18adf76f93f584e87ad06ad53f7b50153
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 19:40:22 2026 +0530

    Regenerate the test inventory, set the badge, unbracket README placeholders

    The four code tracks moved the count from 1157 to 1174 runnable cases
    (1 skipped), so docs/test-cases.md is regenerated and the README badge
    follows its Total (testing-§5). The README's three angle-bracket
    placeholders are written without brackets, since CurseForge strips them
    as unknown HTML (RA-13, QC-16).

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

commit 4c5670c2b929fa85d6c41fb5ffdfeae8dad0ae49
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 19:38:16 2026 +0530

    Add the smoke checks the 2026-10-25 fixes owe, and follow the relabels

    The code tracks changed what a player can see in game, and each change
    needs an in-client check the mock cannot make: SEND-6 rewritten for the
    client-confirmed General with a reordered-channel step (F-007), SEND-7
    for the lockdown lift after an encounter or key (F-003), PAD-16, PAD-17
    and DIAL-42 for the parked buttons (F-006), DIAL-43 and SHINE-4 for the
    cheaper repaints (F-001), DEGRADED-2, EDIT-34 and LAYER-5 for the audit's
    help row, labels and clamped modals. Existing rows take the new button
    labels and Master opacity, and Pending sign-off lists what is owed.

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

commit 772b5bf82a753acd42705be00df1d09f5ac2cab7
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 19:36:27 2026 +0530

    Spill the hub's taint notes and limitations; sync the docs to the fixes

    The hub carried full bodies where it owes summaries (RA-22, QC-22): Taint
    Notes and Known Limitations move to docs/taint.md and
    docs/known-limitations.md, both registered as Tier 2 rows; Module Map,
    Settings Schema and Frame layering shrink to a summary and a link. The
    named non-setting state is one list in schema.md, each key with its
    owner and every writer (QC-23).

    The same pass clears the drift (RA-04, QC-24, QC-25): the locked
    default, Master opacity, the Share and PinNodes leftovers, scope.md's
    gate claim. Register row QC-R6 drops the Share window, cites commits,
    covers the clamped non-toplevel modals (RA-18) and names the dial screen
    catcher (RA-21); a new row records the color gray-outs (RA-15). The
    compat page counts 31 shims and adds UnitDisplayName (RA-23). Known
    limitations gain General confirmed at /1, the late lockdown lift and a
    newer LibKa0s from another addon (RA-11), and module-map.md follows the
    code tracks.

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

commit ba453b7ab78ddddba2b547ca1b5954c443810695
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 19:23:03 2026 +0530

    Shard the test gate after measuring where its time goes

    testing-§14 asks for the measurement first. Serial: 89.7 s wall on
    32.0 s CPU (35%), and 71 s of it is test_vendor_sync's byte check of
    the 5892-file payload, one batched git cat-file waiting on ../LibKa0s
    over the WSL2 mount. The kit already caches chunks and batches blobs,
    so the remaining lever is jobs = "auto": 72.9 s with the same totals,
    exit code and transcript, diffed line for line (RA-20, QC-28).
    testing.md records the figure, names test_page_groups_nesting and warns
    that plain lizard misreads PL.VisibleSections.

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

commit f2aeb8ceabb7f16ebf44972deb4d88a07640d9fe
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 19:12:53 2026 +0530

    Drop retired lint grants, ship no logo .jpg, label BuiltIns TOC lines

    .luacheckrc no longer grants GetBindingAction, SetBinding, SaveBindings,
    GetCurrentBindingSet (the retired key box) or GetChannelName (General is
    now read through C_ChatInfo): no shipped file calls them, and the grants
    would let a reintroduced key editor lint clean (RA-05, F-005, QC-29).
    .pkgmeta ignores media/logos/*.jpg beside the .png (RA-17, QC-20). The
    six BuiltIns_* TOC lines append to NS.BuiltIns.order, so they are
    LOAD-BEARING (b), with In Group last (RA-19, QC-26).

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

commit 71ad5f60b3bd68a6d22e4a6f51a029c9867d244f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:56:36 2026 +0530

    Record the 2026-10-25 perf re-measure: both scenarios back under their ceilings

    padRebuild12 66290.8 and dialOpenClose 1997.1 B/iter after the shine and
    highlight guards; the bisection, the causes and the F-006 write change go
    into docs/performance.md, and tests/perf.lua notes that no ceiling moved
    (F-001, RA-01).

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

commit 71ad5f60b3bd68a6d22e4a6f51a029c9867d244f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:56:36 2026 +0530

    Record the 2026-10-25 perf re-measure: both scenarios back under their ceilings

    padRebuild12 66290.8 and dialOpenClose 1997.1 B/iter after the shine and
    highlight guards; the bisection, the causes and the F-006 write change go
    into docs/performance.md, and tests/perf.lua notes that no ceiling moved
    (F-001, RA-01).

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

commit 71ad5f60b3bd68a6d22e4a6f51a029c9867d244f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:56:36 2026 +0530

    Record the 2026-10-25 perf re-measure: both scenarios back under their ceilings

    padRebuild12 66290.8 and dialOpenClose 1997.1 B/iter after the shine and
    highlight guards; the bisection, the causes and the F-006 write change go
    into docs/performance.md, and tests/perf.lua notes that no ceiling moved
    (F-001, RA-01).

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

commit 71ad5f60b3bd68a6d22e4a6f51a029c9867d244f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:56:36 2026 +0530

    Record the 2026-10-25 perf re-measure: both scenarios back under their ceilings

    padRebuild12 66290.8 and dialOpenClose 1997.1 B/iter after the shine and
    highlight guards; the bisection, the causes and the F-006 write change go
    into docs/performance.md, and tests/perf.lua notes that no ceiling moved
    (F-001, RA-01).

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

commit 71ad5f60b3bd68a6d22e4a6f51a029c9867d244f
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:56:36 2026 +0530

    Record the 2026-10-25 perf re-measure: both scenarios back under their ceilings

    padRebuild12 66290.8 and dialOpenClose 1997.1 B/iter after the shine and
    highlight guards; the bisection, the causes and the F-006 write change go
    into docs/performance.md, and tests/perf.lua notes that no ceiling moved
    (F-001, RA-01).

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

commit 3712c6657a5815a27994c76d9e8f2e89210db03e
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:55:32 2026 +0530

    Park released buttons and wedges armed; disarm only what a rebuild leaves out

    Every rebuild disarmed every pad button and dial wedge before arming them
    again, so SendEngine.Arm's unchanged-line fast path never fired and each
    rebuild paid four secure writes per button (F-006, RA-06). A release now
    parks the button armed (the pool hides it, so it takes no click); after the
    rebuild places its buttons, and after a release, every button the pool did
    not take back is disarmed. Writes stay inside Apply and Release, which
    refuse in combat. New cases pin zero line writes on an unchanged rebuild and
    no type on any button or wedge outside the active set.

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

commit e792882d5f2cfbe3d56fa1878e91c89ee0cf41a2
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:49:55 2026 +0530

    Split the secure-path rebuilds into named helpers

    Complexity only (performance-section 11), no behavior change. DS.Load's
    per-ring attributes and buttons, Pad.Apply's release, sizing and finish,
    Dial.Apply's rebind, ring load, scale and log, and S.ApplyAll's context,
    plan settling, plan building and show log each move to a local helper.
    CCN: DS.Load 19 -> 7, Pad.Apply 18 -> 9, Dial.Apply 17 -> 9, S.ApplyAll
    28 -> 7 (RA-02).

    The write order was pinned first: a scratch characterization logged every
    SetAttribute, SetFrameRef, Execute and state driver, every message and debug
    line across twenty rebuilds (situations, test mode, Preview as, the edit
    preview, a combat-queued rebuild, tabs, surfaces off and on) plus each secure
    frame's final attributes. The 6755-line log is byte-identical before and after.

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

commit 20735fd003672d9531a57d530dede9bd31b7c8a0
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:47:43 2026 +0530

    Split G.ReusableCallouts into its three steps

    performance-§11: G.ReusableCallouts was CCN 24 in the sighted shadow (RA-02, review F-002).
    Finding each callout's group part, the sort comparator and the labeling with repeat numbers
    become reuseOwners, reuseBefore and reuseLabel; the function keeps the collect-sort-label
    order. No behavior change: the Reuse cases in test_page_groups, the characterization case
    among them, pass unchanged.

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

commit 828fbbb601c9d54185300f99e5343e94ba57c2d5
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:46:36 2026 +0530

    Characterize G.ReusableCallouts' fallbacks before its refactor

    testing-§13: a nameless group or callout (read by its id) and a callout no group holds (no
    group part, no color, sorted first) had no case. Green against the function as it stands.

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

commit 80a0fbb297eb5966ca350c03888b96cbe09be02d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:45:55 2026 +0530

    Split the Groups page suite at the layout-§1 cap

    tests/test_page_groups.lua sat at exactly 1500 lines, so the next Groups-page case could not
    land (RA-09, review F-009). Its last four groupings (nested groups, the Preview table, Inherit
    when conditions, a pad title's right-click) move whole to test_page_groups_nesting, with the
    open, pick, bare and MPLUS helpers they use; the new suite is registered after its parent.
    67 cases before and after (48 + 19); 1115 and 418 lines.

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

commit d68a7c6d58e8ebf5fab5b51221ca3efb6deb0a93
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:44:58 2026 +0530

    Prove every disabled event handler inert, and press the toggle key disabled

    Step 6 proved reach for PLAYER_REGEN_DISABLED alone and step 8 never
    pressed the Toggle Comms Pads key while disabled (RA-12, QC-03). Step 6
    now fires every R_on event at its handler through __fireUnconditional and
    asserts reach per event with no write, print, show or timer; a new step 8
    case presses the key through __pressKey. Firing them all showed that
    Situation's handler armed its coalesce timer and Restrictions' re-read and
    armed the late re-read while stood down, so those handlers now return at
    once when the latch is down.

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

commit 0b5a6aada389b11dc802ffc75e9f2237e6258722
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:43:28 2026 +0530

    Split the dial shine recipe case and the preview's JSON writer

    Complexity only (performance-section 11), no behavior change. The recipe
    case's per-layer checks move to named helpers with the same assertions and
    messages; the preview tool's encode becomes one writer per Lua type. The
    tool's dump at radii 100,150 is byte-identical before and after (64 scenes).
    Both sat in the measured shadow above CCN 15 (RA-02).

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

commit ecfdfb239d1413a8d3dd4bd7c79a6e943184d689
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:43:05 2026 +0530

    Split V.PreviewLines into one helper per form of `/qc preview`

    performance-§11: V.PreviewLines was CCN 16 (RA-02, review F-002). Bare, list, off and a
    name each get a named helper; the dispatcher keeps the order of the checks (off is tested
    before the preset lookup, which already skipped it). No behavior change: the characterization
    case from the previous commit and the preview suites pass unchanged.

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

commit 13947b9fd96351067d1986cc5f17dea8d40c4e7d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:42:03 2026 +0530

    Characterize V.PreviewLines before its refactor

    testing-§13: a refused bare or named start, a repeat of the preview already on, list's
    "now" header and off with nothing on had no case. Green against the function as it stands.

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

commit 0772b440f7920f80b28a34a3281b16979ff99b74
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:41:33 2026 +0530

    Split R.SkinFor, R.Look and R.PointerUpdate into named helpers

    Complexity only (performance-section 11), no behavior change: the edge read,
    the Group labels and Paging looks, the pointer's aim and its hover each move
    to a local helper. CCN 16 -> 13, 22 -> 10 and 17 -> 5; the existing render,
    dial and page suites cover each path (RA-02).

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

commit 3218d02513802da09fce59e52de1992303c470e4
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:41:19 2026 +0530

    Count channel 1 as General only when the client says it is

    Any joined channel 1 used to count as General, so a player whose /1 is a
    custom or reordered channel sent "General" callouts there (RA-07, F-007).
    GeneralJoined now asks C_ChatInfo.GetGeneralChannelLocalID, the id
    Blizzard's own chat code reads to find the zone General channel, and
    counts it only when that answer is a plain 1; never the localized name
    (localization-§4). Anything else falls back to Say, as when General is
    not joined. The mock models the id instead of GetChannelName.

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

commit 0db201b7eadd82f6a68a25814245a2087bb7b53a
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:40:56 2026 +0530

    Dispatch W.ResolveValue on the row's shape, one resolver per shape

    performance-§11: W.ResolveValue was CCN 17 (RA-02, review F-002). A module-level RESOLVE
    table holds the character and specialization rows; any other id row goes to resolveIdValue
    (its whole kind first, as before) and the rest to resolveTokenValue. No behavior change: the
    characterization case from the previous commit and the existing ResolveValue cases pass
    unchanged.

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

commit 825a62b52904307e32fd53d0668f4bb95166aa98
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:40:47 2026 +0530

    Split PL.Compute's cell size, blocks and box size into helpers

    PL.Compute sat at CCN 19 against the release gate's 15 (F-002, RA-02).
    The cell size, the collapsed-or-collected blocks and the box size are
    named helpers now; the layout it returns is unchanged.

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

commit dbcef921b8dfe06bb622cfdfdb8813fba6dd1410
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:39:44 2026 +0530

    Characterize W.ResolveValue before its refactor

    testing-§13: the character row's accept and refuse, each refusal's reason, a token row's
    "all" and an unknown row had no case. Green against the function as it stands, so the
    refactor that follows has to keep every answer.

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

commit 81d90185a00a10b35e18e3e01650feca0d9d1493
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:39:43 2026 +0530

    Split W.Summary's key-level and id-row phrasing into named helpers

    performance-§11: W.Summary was CCN 19 in the sighted shadow (RA-02, review F-002). The key
    level's phrase and an id row's name-or-count move to keyLevelSummary and idSummary; the
    dispatcher keeps the order of the checks. No behavior change: the drawers and arena cases in
    test_groups_when cover every branch.

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

commit 2e678bc18d296749c0acc63e47570091487f0339
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:39:37 2026 +0530

    Split oldDungeonWhen, expandOne and EditPresetKey below CCN 15

    All three sat above the release gate's CCN 15 (16, 19 and 23; F-002,
    RA-02). oldDungeonWhen's two scans and expandOne's live, spell and baked
    kinds become named helpers; EditPresetKey reads its kinds from one
    ordered table. No behavior change.

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

commit 7eb71156d33e6bff30a81e67810162092a993799
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:38:04 2026 +0530

    Delete W.HasAll, which only the tests called

    No shipped code asks whether a When row offers the whole-kind checkbox; the editor reads the
    ALL table directly (RA-08, review F-008). Its three test asserts go with it; the same cases
    still pin All battlegrounds, All dungeons and raids and All arenas through Summary and
    ResolveValue.

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

commit 1e47255713acc32ff5de1b39f8319afb960d3e38
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:37:39 2026 +0530

    Pin oldDungeonWhen, EditPresetKey's order and expandOne's edges

    Characterization cases ahead of the CCN refactor of the three (RA-02,
    testing-13): which stored Whens step 5 reads as the shipped M+ one, the
    order EditPresetKey reads a When's kinds in plus open world, and the
    live count, flattening and empty values of token expansion.

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

commit a2690539e73b7f426d8cc1de8fd2956666103400
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:37:10 2026 +0530

    Move a dial's slice highlight only to another slice or shape

    Bisected the dialOpenClose rise (1356.6 -> 2317.1 B/iter) to the dial polish
    work, not the shine merge: 22283b7 (+320, the gap's placement) and c8a8994
    (+1040, the pointer's per-frame tracking now lights a slice and hovers its
    wedge, the tooltip included). Re-placing the highlight on the slice it
    already sits on was the avoidable part; the hover's tooltip is the feature's.
    dialOpenClose is 1997.1 B/iter, under its 2048 ceiling (F-001, RA-01).

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

commit 36e6cd3cc97fc61a9b4b92787d7a7b653501b884
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:36:54 2026 +0530

    Clamp the modal windows to the screen; keep them non-toplevel

    frame-layering-§4 asks modals to be toplevel and clamped (RA-18, audit QC-21). Clamping is
    taken. Toplevel is not: the client raises a toplevel window to the top of its strata on every
    mouse-down, so the click on the popup's Choose icon... would lift the popup over the icon
    browser's level band as the browser opens. The catcher already leaves each modal the only
    clickable frame in its strata, so a raise gains nothing. test_layers pins both outcomes; the
    register row QC-R6 is to say why.

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

commit 08f14b64b8801ae2b421ef26e6999e8f262f886d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:36:24 2026 +0530

    Drop Restrictions' test-only CanSendChat and ActiveReason

    No shipped code called either; the surfaces read Snapshot and ActiveSet
    (RA-08, F-008). The suite now reads the same two answers off Snapshot, so
    every case keeps its intent and the count does not move.

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

commit c2af53a806d7ee102edac3c419b766b83ea4a316
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:35:24 2026 +0530

    Re-read restrictions when an encounter or a key ends

    The header promised a refresh on ENCOUNTER_END and CHALLENGE_MODE_COMPLETED
    but nothing wired either, so a chat lockdown that cleared after its last
    event kept the padlocks and the "may not have been sent" line (RA-03,
    F-003). Restrictions now owns ENCOUNTER_END in FEATURE_EVENTS; Situation,
    which owns CHALLENGE_MODE_COMPLETED, forwards it. Both re-read now and once
    more 1 s later, since the client's flag can lag its own event; the
    stand-down cancels the late re-read. The tests fire the events through
    the mock instead of calling Refresh directly.

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

commit 4b8f28fc0e09910d41590383ba5061a619327b88
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:35:19 2026 +0530

    Split SeedFromOverlay and ValidWhenValue into named helpers

    Both sat above CCN 15 (30 and 16, F-002, RA-02). SeedFromOverlay's
    guard, customized-set marking, overlay seeding and per-surface
    conversion become named helpers; ValidWhenValue dispatches to one check
    per row kind. No behavior change.

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

commit 8da5da4a731c868a25f403fba1a48471fcbd4802
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:35:00 2026 +0530

    End the three delete buttons in an ellipsis; name Duplicate's noun

    options-ui-§21: a button that opens a confirmation ends in "…", and a button that acts on an
    instance names it (RA-16, audit QC-19). Delete group…, Delete pad… and Delete dial… use the
    literal U+2026 as Choose icon… does; Duplicate is Duplicate group. The locale keys move with
    the labels, and the page and layout tests that find the buttons follow. No stored path moves.

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

commit 44cb03e8235845c73c063519a251ed1f2eb3155e
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:34:11 2026 +0530

    Pin SeedFromOverlay's raw-profile repair and ValidWhenValue's whole kind

    Characterization cases ahead of the CCN refactor of both functions
    (RA-02, testing-13): a raw profile with missing or junk registry keys
    and surfaces, and the whole kind accepted on a place row only.

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

commit 3acd087947cdd76b5bd27f429b2e5635054ef07b
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:33:20 2026 +0530

    Print the library-absent help row as `cmd  desc`, without the em dash

    slash-commands-§1: the degraded stub must not copy the library's FormatRow, so its help and
    landing rows are the verb, two spaces and the description, plain (RA-14, audit QC-17). A new
    case pins the row shape on a real library-absent load.

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

commit 445cff9558c3320eb5ef87ffa1a41e1c5b613bde
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:32:26 2026 +0530

    Delete Tok.UsesGroupToken and Lib.DeleteCallout

    Neither has a shipped caller; only their own test asserts called them
    (F-008, RA-08), and no feature asks for them. The group-token test keeps
    its expansion assert; the DeleteCallout case goes with its function.

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

commit 1b14ed66aa4a6e23d7f572e958ef506eee5c4aa3
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:31:59 2026 +0530

    Paint a pad button's shine only when its look or size moved

    Every rebuild repainted the shipped Gloss fade on every button, outside the
    look signature: a fifth of padRebuild12's bytes (87026.8 -> 66290.8 B/iter).
    The shine table is reused while the button look's signature holds and a
    release never hides the shine layers, so an identity-and-size guard keeps an
    unchanged button's paint (F-001, RA-01).

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

commit f804233924d7ef14509568282de09249a0606855
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:31:15 2026 +0530

    Build Library.Children's sort keys once per call

    The comparator lowercased both names on every comparison, on every pad
    and dial rebuild (F-011, RA-10). The keys are now built once per child
    before the sort; the order is unchanged.

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

commit 33279f1f6f65608993c65750cf404f5208597bb0
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:26:22 2026 +0530

    Spec and plan for fixing every 2026-10-25 review and audit finding

    RA-01..RA-24 consolidate F-001..F-011 and QC-03..QC-30 with the owner's
    three rulings (QC-18 kept and recorded, General verified else Say, LibKa0s
    stays on v1.77.0), split into four parallel code tracks on disjoint files,
    an integration step, a docs-and-config track and a final record.

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

commit 6f396c7341d4a1eac4a01a1422c2f1aa7b582733
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 18:25:02 2026 +0530

    Record the 2026-10-25 review and standards audit bundles

    docs/reviews/2026-10-25/ (dev-copilot:review, whole repo: 0 critical, 0
    high, 3 medium, 8 low) and docs/audits/2026-10-25/ (standard v2.88.0: 18
    roots, 14 MUST failures, all low), frozen as written.

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

commit 18a2b55d98f154b311dba0eb90824e8e854ebc1a
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 16:22:58 2026 +0530

    Record the owner's smoke pass for the 2026-10-25 run

    EDIT-32, EDIT-33, PREVIEW-2, DIAL-4, BG-1, BG-4, BG-5, BG-7, BG-8 and BG-9
    passed in game; no check is owed.

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

commit 3abbaa9fee0242b4d1590340ac7841c50633b051
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 16:06:07 2026 +0530

    Fix the Alterac Valley pad test for the A-Z order after the FW rename

    With FW East and FW West Tower renamed, Vanndar sorts last and takes the lone
    nineteenth row, so the test checks Aid Station and Balinda as the paired
    blocks and Vanndar as the full-width one.

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

commit 3abbaa9fee0242b4d1590340ac7841c50633b051
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 16:06:07 2026 +0530

    Fix the Alterac Valley pad test for the A-Z order after the FW rename

    With FW East and FW West Tower renamed, Vanndar sorts last and takes the lone
    nineteenth row, so the test checks Aid Station and Balinda as the paired
    blocks and Vanndar as the full-width one.

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

commit dca3aaa624fc1f65f7ef63ed912575ea122e18ab
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 16:03:43 2026 +0530

    Eye of the Storm towers by owner; Frostwolf towers renamed FW East and FW West

    Blood Elf Tower and Fel Reaver Ruins are Horde-owned, so red; Draenei Ruins
    and Mage Tower Alliance-owned, so blue (none neutral). Alterac Valley's East
    and West FW Tower are named FW East Tower and FW West Tower, so they sort
    beside each other; their callouts still name the full Frostwolf tower.

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

commit 88f92fc969b282b462aa6b256882febe5288bb62
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 14:23:03 2026 +0530

    Battleground icons take faction and location colors; actions keep theirs

    A faction-themed location takes its side's color: Alterac Valley's generals,
    captains, bunkers, towers, graveyards and huts Alliance #2AA2FF or Horde
    #FF4040, Snowfall GY neutral #FFD100; Eye of the Storm's Draenei Ruins and
    Blood Elf Tower by side, Fel Reaver Ruins and Mage Tower neutral; Ashran's
    Road of Glory neutral. Neutral maps' white icons take a color for what they
    are (Stables and Warsong Gulch's Midfield brown, the Quarries and Twin Peaks'
    Bridge stone, Isle of Conquest's Hangar sky). Attack and Contest go crimson,
    Defend and Hold cyan, so no action reads as a faction. Seed data only: no
    migration (owner).

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

commit 6240120b47922e655fd0f229793e69f06c202e53
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 14:14:38 2026 +0530

    Dial rings place battleground nodes one slice each, with no empty slices

    Node sets were pinned to their compass winds on an eight-slice ring, so a set
    with fewer entries drew blank slices (Arathi Basin two, Ashran two). Every
    ring now follows the dial's slices: under Auto one slice per item, paged past
    the limit. A group with children holds its own callouts as one wedge first,
    then its children A-Z. The compass field is retired: DL.PinNodes, the wind
    column of the battleground node rows, its seeding and tools/derive-winds.py
    are gone (no migration; a stored compass is left unread).

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

commit 8898e7420cd8147daedba5bfb369b397764dd54c
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 14:01:25 2026 +0530

    Nested groups list A-Z by name everywhere

    Library.Children sorts a group's children by name, case-insensitive, then by
    the order they were made. The Group picker, Parent group, the pads' sections
    and tabs, and the dials' rings all read it, so a battleground's nodes are
    alphabetical everywhere (owner, 2026-10-25).

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

commit c907b316eeffc46d3d1eb3fa54ba920c7cd65226
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 13:55:59 2026 +0530

    Preview as lists every season dungeon and each season raid at Mythic, A-Z

    The menu had one M+ dungeon (Windrunner Spire) and the first raid at all four
    difficulties. It now has one M+ entry per current-season dungeon (mplus:<id>)
    and one Mythic entry per current-season raid (raid:<id>), each list sorted by
    the client's name. The edit preview picks the dungeon or raid its group's
    Instance row lists, and bakes a raid group at Mythic, else at the group's own
    first difficulty, so a Heroic-only group still shows.

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

commit 2f0e2b3d826a10929400abf2a9475efa60e1bc3a
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 12:36:29 2026 +0530

    Remove the Share (export/import) feature before v0.1.0

    Share is pulled from the first release, to be rebuilt later. Removed:
    modules/Share.lua (the !QC1! codec, checks and report), settings/Share.lua
    (the Share page), Library.Import, NS.State.share, the vendored LibDeflate
    and LibSerialize (Share was their only consumer), the Share locale strings,
    and the test_share and test_page_share suites with the import cases in
    test_library, test_channels, test_layers and test_setup. Groups keeps the
    literal-escape helper it borrowed from Share as a local. Docs, smoke checks
    (SHARE-1..6), the test inventory and the badge follow (1157 tests).

    This commit's parent holds the full working implementation.

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

commit 2f0e2b3d826a10929400abf2a9475efa60e1bc3a
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sun Oct 25 12:36:29 2026 +0530

    Remove the Share (export/import) feature before v0.1.0

    Share is pulled from the first release, to be rebuilt later. Removed:
    modules/Share.lua (the !QC1! codec, checks and report), settings/Share.lua
    (the Share page), Library.Import, NS.State.share, the vendored LibDeflate
    and LibSerialize (Share was their only consumer), the Share locale strings,
    and the test_share and test_page_share suites with the import cases in
    test_library, test_channels, test_layers and test_setup. Groups keeps the
    literal-escape helper it borrowed from Share as a local. Docs, smoke checks
    (SHARE-1..6), the test inventory and the badge follow (1157 tests).

    This commit's parent holds the full working implementation.

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

commit e5062ae852beedb5f66bcd2647836b1b1fa7a4ad
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Oct 24 22:38:09 2026 +0530

    Record the owner's smoke pass for the 2026-10-24 run

    The owner reported every in-client check of the keybindings, settings
    layout and frame layering run passed: KEY-4 to KEY-6 (with the QC-RV3
    one-key-button follow-up), LAYOUT-1 to LAYOUT-5 and LAYER-1 to LAYER-4
    now carry their pass on the Result line. Pending sign-off no longer
    lists them and says no check is owed.

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

commit 207d3f8e805c1f7bc7147c80f7aacdd4a3b3bfa4
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Oct 24 17:06:50 2026 +0530

    QC-RV3: address review — roll the test_keybinds header to OptionsKeybinds minor 4

    The header comment still cited OptionsKeybinds minor 3; QC-RV3 vendored minor 4 (LK-96).
    Comment only.

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

commit 207d3f8e805c1f7bc7147c80f7aacdd4a3b3bfa4
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Oct 24 17:06:50 2026 +0530

    QC-RV3: address review — roll the test_keybinds header to OptionsKeybinds minor 4

    The header comment still cited OptionsKeybinds minor 3; QC-RV3 vendored minor 4 (LK-96).
    Comment only.

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

commit 54d637aec216b3af519a111fa9bdaa512d71e409
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Oct 24 16:56:00 2026 +0530

    QC-RV3: re-vendor LibKa0s v1.77.0 after LK-96; one key button docs

    LK-96 re-closed the local v1.77.0 tag (afae2f7 -> 2f2b2e2) with the
    owner's follow-up to item 015: one key button and Clear per row on the
    in-addon Keybindings tab. Copy libs/LibKa0s and tests/_kit whole from
    the moved tag again. Only OptionsKeybinds changed (minor 3 -> 4); the
    kit stays at revision 42 (bindings_xml.lua's keybindThroughTab writes
    slot 2 through the model on a one-button row). prune-icons.lua removed
    nothing; the CLAUDE.md provenance line is unchanged. No public Options
    member was added, so the degradation stub is unchanged.

    General > Keybindings is now described as one key button and Clear,
    with "<key> +1" and a tooltip when the game's page holds a second key,
    in README.md, docs/settings-panel.md, the settings/Panel.lua comment
    and docs/smoke-tests.md. KEY-5 and KEY-6 are rewritten (SM-QC-RV3) and
    listed under Pending sign-off with KEY-4, which QC-KB had not listed.
    No addon test drove slot 2 through the tab. Bindings.xml, NS.BINDINGS
    and the labels are untouched. Recorded as a new section of
    docs/revendor/2026-10-24-v1.77.0/05_SUMMARY.md.

    Refs 015.

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

commit 1b6ca2082e227311c284c8802971f50709a6c227
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Oct 24 14:36:48 2026 +0530

    QC-LY: address review — retire the pre-020 tab names from docs and comments

    The review found present-tense text still naming the tabs item 020 renamed:
    - docs/schema.md: the pads/dials rows and the member-row list now name the
      Header, Section titles and Labels tabs (Slice labels, Group labels and
      Tooltip headings), and dial.slice.gap is the Layout tab's Slice gap (it
      moved from Slices, QUI-L21; the path kept).
    - docs/ARCHITECTURE.md: Section titles' look in the module table; the member
      rows' prose names Layout (Wheel until item 020), the Labels tab's headings,
      Slice gap on Layout, Header and Section titles, and the dial's Icons rows
      spliced after its Labels rows, Icon offset beside Icon size.
    - defaults/PadStyle.lua, settings/Groups.lua: comments name Header, Section
      titles, the Labels tab's Group labels heading and the What it sends tab.
    - docs/smoke-tests.md (the fonts' locale note) and docs/module-map.md (the
      editors' test row) carried the same names; fixed alike.
    Comments and docs only; no behaviour changed.

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

commit e364d64f3fca2f919c92373cf50e89466c85eebb
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Oct 24 14:21:48 2026 +0530

    QC-LY: lay out the settings pages by subject (item 020, 32 changes)

    Item 020 (settings layout) for QuickComms: move, regroup and relabel only.
    No stored path, default, range, choice set or behaviour changed, and no row
    was added or removed: tests/test_schema.lua's new layout guard pins all 233
    rows (path -> type, default, min, max, step, choices, sessionOnly) against
    tests/schema_pins.lua, generated from HEAD before the first edit.

    General page
    - QUI-L01/L02: Behavior under two headings, Sending (solo | spam guard,
      sound | drop notes) and Pads and dials (put instance-specific groups first |
      LOCKDOWN tag, then why tooltips); three labels reworded, tooltips unchanged.
    - QUI-L-new2: the header Defaults tooltip is O.ResetAllTooltip(
      O.KEYBINDS_UNCHANGED); the host lead string is gone.

    Groups page
    - QUI-L03: Inherit when conditions moves to the top of When (group = When,
      still before group.when; G.InheritItem drawn by Groups_When), tooltip and
      the inheriting line point "above"; the page's Defaults still resets it.
    - QUI-L04/L05/L-new3: General runs Name | Enable this group, the icon, Parent
      group, Duplicate | Delete group, then a gap, a gray line and Restore.
    - QUI-L06: Defaults tooltip rewritten (no retired dial reset; icon and parent
      kept). QUI-L08: the Preview tab and the popup heading read What it sends.
    - QUI-L34: the band is one row (picker 0.4, New group 0.25, Preview while
      editing 0.35; G.BAND_H 44, O.BANNER_H). The full label fits; not shortened.

    Pad page
    - QUI-L09/L10: strip outside in (Window, Header, Section titles); Section
      title height. QUI-L12/L13/L14: Buttons runs Size, Font, Background, Border,
      Button glow, Shine; every swatch reads Background color; the Icons glow is
      Icon glow and holds the glow offsets (no Offset heading); Buttons' Glow
      style tooltip names the Icons tab's default knobs.
    - QUI-L07: Add group above the list; hint says "Add one above."
    - QUI-L15, L18, L36, L-new1, L-new3: Unlock/Lock all pads (tooltip names Lock
      frame on the General page > Master controls), Defaults tooltip, Pad scale
      (multiplied-by-Master-scale tooltip) and Button spacing, Faded opacity,
      Enable this pad.

    Dial page
    - QUI-L22/L21: Wheel is Layout; Slice gap moves there (row physically after
      Ring radius, Gap heading gone); renderLayout draws Open at under Position.
    - QUI-L19: one Labels tab: Slice labels, Group labels, then Tooltip.
    - QUI-L23/L24/L25/L26: Slices Colors; Hub, Hub border, Hub circle; Page row
      (Distance below labels); Page indicator, Indicator border, Indicator
      background with the padding beside its toggle. Gates unchanged.
    - QUI-L27: Size, offset and crop: Icon size | Icon offset, then Zoom
      (Settings.IconRows takes the row to splice after Icon size).
    - QUI-L08/L28/L29/L35/L-new3/L07: Ring map; Defaults tooltip; a static gray
      key line on General (no key box, no readout); slice for wedge in the Dial
      page tooltips (slash help and test-mode chat left alone); Enable this dial;
      Add group above the list.

    QUI-L32 needs no commit: landed by QC-KB 31f7221, recorded in the bundle's
    exceptions.tsv with a proof command.

    Tests first: tests/test_layout.lua (one case per page or tab group) and the
    guard went red for the right reasons (55 failing), then green. Existing page
    tests updated to the new labels, tab names and order. Locale keys replaced
    in locales/enUS.lua (the only locale). Docs: settings-panel (Behavior
    section, every page's map and prose), README Usage and Version History and
    badge, ARCHITECTURE, module-map, schema, data-flow, testing, regenerated
    test-cases; comments naming old tab names in modules/ updated (XC-12).
    smoke-tests LAYOUT-1..5 (SM-QC-LY), not run.

    Deviations: QUI-L14's "(px)" unit form had no target (no glow offset label
    carries a unit), so no label changed. QUI-L34 kept the full "Preview while
    editing" label (0.35 of the band). A gray hint/key line is a TextRow, not a
    heading (options-ui-§7).

    Refs: item 020.

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

commit 7bdbc0536ad0cd7bf1b640742b88152bd93557a2
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Oct 24 12:55:53 2026 +0530

    QC-RV2: re-vendor LibKa0s v1.77.0 after the tag moved (LK-95)

    LK-95 re-closed the local v1.77.0 tag (78240f7 -> afae2f7) with the
    M3 settings-layout surfaces. Copy libs/LibKa0s and tests/_kit whole
    from the moved tag again. Only OptionsCompose changed (minor 8 -> 11);
    the kit stays at revision 42. The CLAUDE.md provenance line stays
    v1.77.0 and records no sha, so it is unchanged. prune-icons.lua
    removed nothing.

    The kit's Options surface-parity case failed on the new
    O.ResetAllTooltip; the library-absent branch of
    settings/OptionsSetup.lua now carries it as an inert member returning
    "". No adoption: QC-LY adopts the layout surfaces. Standards half: no
    drift (the reference is unversioned).

    The re-vendor is recorded as a new section of
    docs/revendor/2026-10-24-v1.77.0/05_SUMMARY.md, not a new bundle.

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

commit 144373446dc77d12192e1d0521f22804f400b8b1
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Oct 24 10:29:43 2026 +0530

    QC-ZS: one LAYERS table, the button and wedge ladders, strip alpha

    Item 030 (frame-layering, standard v2.88.0; LibKa0s v1.77.0), the strata
    changes the owner accepted for QuickComms (accepted.json: QUI-Z01, Z02, Z03,
    Z04, Z06, Z09, Z10, Z11; the STRATA_MODEL overrides applied).

    - QUI-Z01: core/Constants.lua NS.Constants.LAYERS = { STRATA, LEVEL }, keyed
      by frame-layering's tier keys (HUD, HUD_POPUP, WINDOW, MODAL, POPUP) plus
      the addon's DIAL_SCREEN and STATIC_POPUP, its header comment the whole stack
      (QC-06's reasoning, the library and Blizzard tiers, the dial covering the
      library console where they overlap: QUI-Z05 not taken, LK-05 deferred).
      Every SetFrameStrata / SetFrameLevel in Pad, SendEngine, PreviewWindow,
      Dial_Render, Glow, IconBrowser and ModalWindow reads it, and every level is
      a base frame's level plus a named offset: the modal bands are now UIParent's
      level + MODAL / MODAL_OVER, each part the base + its offset (same numbers on
      a client whose UIParent is level 0). MW.LEVEL, LEVEL_OVER, STRATA and
      CONFIRM_STRATA stay as aliases of the table.
    - QUI-Z02: a pad button's edge frame at B+1 and its icon frame at B+3
      (IconStyle.IconFrame, at the level its dress names), the button glow one
      over the edge and the icon glow one over the icon frame (Glow.FRAME_LEVEL 2
      split into Glow.BUTTON_LEVEL / ICON_LEVEL, both 1): no tie left.
    - QUI-Z03: PadRender.Overlay, a mouse-off overlay frame at B+6 holding the
      label and padlock (OVERLAY 0) and the dim, cool and flash veils (OVERLAY
      1-3), so a refused button dims whole and the flash lights over the glows.
    - QUI-Z04: the same on a dial wedge: icon frame W+1 (H+3), its glow H+4, the
      overlay W+4 (H+6), under the hub front (H+20).
    - QUI-Z06 (local half, as STRATA_MODEL modifies it): the Share window keeps
      the library's FULLSCREEN, named as the WINDOW tier; the icon link window
      keeps its post-hoc lift, now to LAYERS.STRATA.POPUP, with a comment naming
      the deferred CopyWindow strata option (no LibKa0s issue was filed for
      LK-05, so the comment points at the standard's open evolution).
    - QUI-Z09, Z10: no strata change; the screen catcher's HIGH tie with the
      Settings panel and the never-raised FULLSCREEN preview window are recorded
      in the table, and the secure fixed point gets its Documented deviations row.
    - QUI-Z11: the pad's drag strip passes ignoreParentAlpha = true (DragHandle
      minor 5), so it no longer fades with the pad.

    Tests first: tests/test_layers.lua (10 cases) through the kit's
    mock_layers.lua recorder pins the table, greps the shipped code for strata
    literals and bare levels, and pins every tier above; it failed on the missing
    table and the strip's alpha before the change. test_glow reads the split glow
    levels. tests/wow_mock.lua answers UIParent's frame level (0).

    Docs: ARCHITECTURE gains a Frame layering section and the secure-fixed-point
    deviation row; module-map, testing, the regenerated test-cases and the README
    badge (1189); smoke-tests LAYER-1..4 (SM-QC-ZS1..4), not run.

    Deviations: QUI-Z08 was not accepted, so its headless pin that the ring draws
    no region is not added; the ring catcher's -1 is still named
    (LAYERS.LEVEL.DIAL_CATCHER) because step 1 routes every level write through
    the table. The modal-band offsets (Bg, window, page, close) are named in the
    table too, which Z01 did not list. No settings row changed; QuickComms has no
    player strata row, so O.StrataTooltip has nothing to serve.

    Refs: item 030.

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

commit 31f72216a2f7c75e042f5ef49350c035b00c6043
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Oct 24 09:01:21 2026 +0530

    QC-KB: own Keybindings category, NS.BINDINGS and General > Keybindings

    Item 015 (launcher-§6 and options-ui-§20, standard v2.88.0; LibKa0s v1.77.0
    OptionsKeybinds):

    - Bindings.xml: every Binding names category="BINDING_HEADER_QUICKCOMMS" and
      none carries a header attribute, so Options -> Keybindings draws a Ka0s Quick
      Comms section of its own with no blank spacer row. Toggle Comms Pads (the Show
      window binding) moves first, then Open Comms Dial 1-4 (XC-01, QUI-L32). The
      binding names are unchanged, so no saved key is lost; the labels are unchanged.
    - settings/SlashVerbs.lua, beside the toggle button: BINDING_HEADER_QUICKCOMMS
      (moved from modules/Dial.lua) and NS.BINDINGS, the one bindings table in
      Bindings.xml order, each with a locale tooltip. The dial rows come from
      Dial.BINDINGS and Dial.Command, so the TOC line now notes it reads Dial at load.
    - settings/Panel.lua: the General page's last tab is the library's
      O.KeybindingsTab({ bindings = NS.BINDINGS, intro = ... }) through
      RenderTabbedSchema's opts.tabs, no `before`; the one host intro line says a
      dial's key follows its place. The Defaults tooltip ends with
      O.KEYBINDS_UNCHANGED (options-ui-§20 SHOULD).
    - This reintroduces an in-panel key editor that b902e35 (2026-10-21) removed
      with the Dial page's Binding tab. The owner's 015 brief supersedes that
      decision; it is done through the library surface, not the retired
      Dial.BindKey (which stays gone). Recorded in docs/ARCHITECTURE.md where the
      removal is described, and in docs/settings-panel.md.
    - Tests first: tests/test_keybinds.lua (NS.BINDINGS order and labels, the strip
      ending in Keybindings, the rows, a key bound through the tab via
      Kit.keybindThroughTab saved to the set in force and toggling the pads, a key
      set via SetBinding showing after UPDATE_BINDINGS, the combat refusal), and
      test_dial's Bindings.xml case rewritten onto Kit.assertBindingsXml.
      tests/run.lua hands Kit.expose a `mock` view forwarding to the newest
      instance's mock, which Kit.keybindThroughTab reads for LibStub.
    - Docs: README Usage/Troubleshooting/Version History and badge, settings-panel
      (General > Keybindings section), ARCHITECTURE, module-map, schema,
      slash-dispatch, compat-layer, data-flow, testing, regenerated test-cases;
      smoke-tests KEY-4..6 (SM-QC-KB1..3), not run.

    Deviations: test_disabled's step 8 is the launcher's left-click and names no
    binding string, so it needed no edit; the press-while-stood-down case there is
    unchanged and green. The research's suggestion to drop wow_mock's own binding
    model for the kit's mock_bindings.lua was not taken (not in the item; the
    existing suites read its tables); the tab's tests run on wow_mock's model.

    Refs: item 015.

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

commit 95a61a47cb15a3cfcbce9110214580967c8f96a5
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Oct 24 08:23:11 2026 +0530

    QC-RV: re-vendor LibKa0s v1.77.0 (kit revision 42)

    Copy libs/LibKa0s and tests/_kit whole from the local v1.77.0 tag
    (78240f7) and roll the CLAUDE.md provenance line from v1.76.0. The
    "LibKa0s icons: all (icon browser)." line is kept; the tag's
    prune-icons.lua removed nothing.

    Minors moved: Core 12, Widgets 15, WidgetsDragHandle 5,
    WidgetsAutocomplete 3, DebugLog 21, Options 30, OptionsIds 3,
    OptionsCombat 2, OptionsCompose 8, OptionsKeybinds 3 (new file),
    PerfPanel 9, SimPanel 6; test kit 41 -> 42.

    The one blocker: the kit's surface-parity case failed because the
    Options degradation stub lacked the four new instance members. The
    library-absent branch of settings/OptionsSetup.lua now answers
    KeybindingsTab and KeybindRows with nil, and KEYBINDS_UNCHANGED and
    StrataTooltip with "".

    Adoption ran without an interview, per the item spec. The Keybindings
    tab and kit 42's binding surfaces are QC-KB's. DragHandle 5 and
    mock_layers.lua go to QC-ZS. O.StrataTooltip and
    Core.RaiseStaticPopups are deferred (run 2026-10-24). No issues filed.
    Bundle: docs/revendor/2026-10-24-v1.77.0/. Payload pointers updated
    in docs/ARCHITECTURE.md, docs/module-map.md and docs/testing.md.

    Refs: OWNER_SCOPE (Ka0sAddonsCommonTasks
    docs/2026-10-24-KEYBINDS_LAYOUT_STRATA).

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

commit 4a3dacabbc184fbb089d11ed9813550540cff8ea
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Oct 24 00:43:56 2026 +0530

    QF-07: the locked window's tooltip shows; record the owner's smoke passes

    A disabled Button runs no OnEnter in the client unless SetMotionScriptsWhileDisabled is on, so the
    locked window's tooltip never showed (owner, 2026-10-24). Each control now takes hover while
    disabled, and the tooltip says the window is disabled while you edit a group with Preview while
    editing on, and to pick another group to see a preview of it. The mock records the flag.

    The owner reported EDIT-18, PREVIEW-10, PREVIEW-11, PREVIEW-12, SEND-6, STATE-6 and TOKEN-1 passed
    on 2026-10-24; the pending list is empty.

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

commit 4a3dacabbc184fbb089d11ed9813550540cff8ea
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Oct 24 00:43:56 2026 +0530

    QF-07: the locked window's tooltip shows; record the owner's smoke passes

    A disabled Button runs no OnEnter in the client unless SetMotionScriptsWhileDisabled is on, so the
    locked window's tooltip never showed (owner, 2026-10-24). Each control now takes hover while
    disabled, and the tooltip says the window is disabled while you edit a group with Preview while
    editing on, and to pick another group to see a preview of it. The mock records the flag.

    The owner reported EDIT-18, PREVIEW-10, PREVIEW-11, PREVIEW-12, SEND-6, STATE-6 and TOKEN-1 passed
    on 2026-10-24; the pending list is empty.

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

commit cb2ceb5995c0f1f7d265623b0787bbcaaf2a8db1
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Oct 24 00:28:07 2026 +0530

    QF-07: module map names the locked window and its re-fill

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

commit 58213a80ed2fbb5659170fc7b302e6353457ff98
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Oct 24 00:22:31 2026 +0530

    QF-07: address review: re-fill the window on a When edit; id rows; the locked close mark

    The review of be3af47 found the dropdown went stale when the edited group's When changed: the pads
    re-baked under the new preset with no announce. The window now re-fills on LIBRARY_CHANGED over the
    edit preview. An arena id row alone maps to Arena, an empty battleground row is unset, and the locked
    close mark no longer lights up on hover. Tests cover the lost QF-02 checks (Preview as off under the
    edit preview, Escape with Preview as underneath) and each kind of When.

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

commit be3af4736c0016ce57da101a52e3f5f88a177642
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Sat Oct 24 00:02:47 2026 +0530

    QF-07: lock the preview window over the edit preview; its dropdown follows the group

    With Preview while editing on, the window's dropdown read Current under an Alterac Valley title and
    a pick in it did nothing visible (owner, 2026-10-24). Over the edit preview the window is now locked:
    dimmed, its dropdown, End preview and close mark disabled, each with a tooltip naming the Groups page.
    Its dropdown shows the preset the edited group's When names (Preview.EditPresetKey), and the edit
    preview's pads and dials bake under that preset (Preview.EditSnapshot) so the window names what they
    show. The Groups page keeps judging where you are.

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

commit e552fb16f64d9b0b8ae5e004232ded0a4196cfdf
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 23:29:29 2026 +0530

    QF-06: docs sweep for the preview follow-ups

    Read the docs every QF item touched against the code: the badge and
    docs/test-cases.md already match `lua tests/run.lua --list` (1170), and
    the five smoke checks (PREVIEW-11, PREVIEW-12, TOKEN-1, SEND-6, STATE-6)
    are pending under Pending sign-off. Gaps found and closed: module-map and
    testing.md gain test_coordinates and the dial_pick helper (testing.md
    also test_preview_window); the README says a preview dial stays open on
    a pick and its Unreleased row names the edit-preview window,
    {coordinates} and General (/1).

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

commit 03caa3d577c5d02603a781e6c674c595b34aea0e
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 23:07:33 2026 +0530

    QF-05: the prebuilts replaced (owner edits, At Stone, Solo on General with {coordinates})

    No migration and no schema step (owner, 2026-10-23: pre-release): only the shipped
    defaults change; a stored profile keeps what it was seeded with, and a new profile or
    Restore built-in groups seeds the new ones. NS.MIGRATIONS still ends at 9.

    Adopted from the owner's SavedVariables (profile Default, read only):
    - Dungeon > Chain pull (bi.mplus.chain): color ff4040 -> fff468 (BI.COLOR.yellow, new)
    - In Group > Hello (bi.group.hello): color ffd100 -> 3fc7eb (BI.COLOR.sky, new);
      text stays "Hello!" (the owner's exception, not "Hello there!")
    - In Group > At Stone (bi.group.stone, new, 2nd): "At stone, WM off.", Smart group,
      gi:tombstone-sbed, b07cff (C.purple)

    Requested on top:
    - Solo: all seven callouts on "general" (/1; Say when channel 1 is not joined)
    - Solo > Rare spotted: "Rare spotted: {target} @ {coordinates}"
    - Solo > Elite help: "Can anyone help with this elite? {target} @ {coordinates}"
    - Solo > World boss: "World boss up: {target} @ {coordinates}"
    - Solo > Event here: "World event starting @ {coordinates}, come join"
      (quest, invite and thanks name no place and are unchanged)

    Not adopted, flagged for the owner: the profile's 14 "%t" texts (Raid > Battle rez,
    Solo > Rare / Elite / World boss, EotS flag kill, WSG and TP kill EFC, ToK kill set and
    four orbs, DHR crystal kill, Ashran captain) are stale seeds from before 65f3a5a, not
    edits; the shipped {target} chip sends the same line.

    Ripple: tests/test_builtins.lua (Solo on General, the four texts, the owner's colors and
    At Stone, no schema step), tests/test_pad.lua (In Group draws eleven), locales/enUS.lua,
    docs/schema.md (no step), docs/smoke-tests.md STATE-6 (pending), docs/test-cases.md and
    the README badge (1170).

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

commit 2ab3a899d9d52e2103c2e7892d714ed59d546b28
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 22:50:44 2026 +0530

    QF-04: the general channel kind (/1, Say when channel 1 is not joined)

    A new channel kind, general, through modules/Channels.lua: prefix /1, chat
    type CHANNEL, resolved at bake time to General when the snapshot says
    channel 1 is joined and to Say otherwise, locked as Say (encounter / PvP).
    Ch.ColorType gives CHANNEL1 for it (Constants.CHAT_COLORS.CHANNEL1 is the
    fallback); the tooltip's Channel: line and the Groups row ask it.

    The snapshot carries general (Compat.GeneralJoined: GetChannelName(1),
    secret-safe), a signature field, refreshed on CHANNEL_UI_UPDATE and
    CHAT_MSG_CHANNEL_NOTICE. Preview's base snapshot copies it; the Solo
    bake-audit snapshot sets it. The echo tracker hears CHAT_MSG_CHANNEL and
    drops a line whose readable channel index is not 1 (SendGuard.IsGeneralEcho)
    before matching; an unreadable index falls to the sender rule. No new send
    path: /1 goes out on the same secure macro click.

    Labels: the channel row "General (/1; Say when not joined)", the tooltip and
    Groups row "General". Ripple: test_disabled's pinned events, .luacheckrc,
    README, ARCHITECTURE, data-flow, compat-layer, module-map, performance,
    schema, the v1 spec's "Superseded in part" line, smoke SEND-6 (pending),
    test-cases.md and the badge (1168).

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

commit 85e87679a3715a68f27a7e34a2dc10ec06c6a23d
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 22:29:12 2026 +0530

    QF-03: the {coordinates} token, re-baked at the press

    A {coordinates} token: your map position as "45.2, 61.8" (x, y in
    percent, one decimal).

    - Compat.PlayerMapPosition / Compat.Coordinates read
      C_Map.GetBestMapForUnit("player") and GetPlayerMapPosition's GetXY,
      every value plain; nil for no C_Map, no map (instances), no position,
      0,0 or a secret. .luacheckrc declares C_Map.
    - Tokens: `coordinates` joins BAKED, `{coords}` is a typed alias;
      missing in a live bake it is dropped and listed (so "{target} @
      {coordinates}" bakes to "%t @" in a dungeon). Tok.UsesCoordinates.
    - Surfaces.BakeContext fills it for the live snapshot only, known by
      identity (snap == Situation.Current()). Surfaces.Slot gives a slot
      whose text uses the token a `rebake` closure; Pad's arm hands it on
      only for an armed live slot.
    - SendEngine: every send button gains an insecure PreClick hook. Out of
      combat, on the acting edge, a button whose meta carries `rebake` is
      re-baked and re-armed through Arm when the line changed; in combat it
      returns before any write. On RESTRICTION_CHANGED into combat (still
      writable) SE.RefreshRebakes re-arms each such button once. This
      replaces the draft's 1 s timer. Perf bucket `coordsRebake`. The click
      edge test moved into a shared local (actingPress).
    - Preview: SlotEcho bakes from a copy of BakeContext with coordinates
      cleared; for the live snapshot the mock keeps the literal
      "{coordinates}", which FillEcho fills at the click (or <coordinates>
      when there is no position); a synthetic preset prints <coordinates>.
    - Lists: C.TOKENS and TOKEN_HELP, the Text row's description,
      P.MOCK.coordinates, locales.

    Tests (1155): test_compat, test_tokens, new test_coordinates (live
    bake, PreClick re-arm after a move, no write when unchanged, no write in
    combat, the combat-edge re-arm once, the dungeon drop, Current and
    edit-preview echoes filled at the click, M+ mock); the mock gains C_Map
    (playerMap, playerPos) and runs PreClick before OnClick on a click;
    test_setup's bucket count 8 -> 9; test_callout_popup's token list.

    Docs: compat-layer (two rows), ARCHITECTURE (taint notes: PreClick;
    event wiring: the combat-edge re-arm; module rows), data-flow,
    module-map, performance (coordsRebake), README (tokens, badge),
    smoke TOKEN-1 (new Tokens theme, pending) and EDIT-18's token list
    (pending re-run), test-cases.md.

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

commit 23bd31f2f426db50a81ed996959d8ea7f0f6fda0
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 22:04:10 2026 +0530

    QF-02: the preview window and start line over the edit preview

    The Groups page's "Preview while editing" put no window up and printed
    nothing: PW.Sync keyed on PreviewAs() alone, and the window's End
    preview, close mark and Escape knew only Preview as.

    - PW.Sync shows the window for the edit preview too; fill titles it
      "<brand> - Preview: <group>" (one line) and selects PreviewAs() or
      Current. A dropdown pick is a Preview as the edited group renders under.
    - P.EndPreview (End preview, the close mark, `/qc preview off`): writes
      behavior.previewOnEdit = false and ends the edit preview, then Preview
      as. `/qc preview off` now ends the edit preview too; with nothing on it
      prints "Preview off." and writes nothing.
    - Escape: P.DismissEditPreview, a session-only mark
      (State.editPreviewDismissed) that G.SyncEditPreview honours, so the
      page's 0 s refresh, re-renders and combat ends do not bounce it back;
      a group switch, the page shown again, a write of the setting or End
      preview clears it. The saved switch is left alone.
    - P.SetEditPreview(gid, quiet) prints "Previewing: <group> (editing)" on
      the off -> on edge; the restart after combat passes quiet.

    The dial echo under the edit preview (spec 1.2): a new headless case
    clicks a wedge through its ring's catcher with the Groups page shown; it
    was green before any change, so no code cause exists and nothing was
    fixed there. PREVIEW-11 (pending) carries the in-client /qc debug check.
    The catcher-pick helper moved from test_preview.lua to tests/dial_pick.lua
    so both suites share it.

    Tests: five test_preview_window cases and two test_edit_preview cases
    (1145). Docs: ARCHITECTURE, module-map, data-flow, settings-panel,
    README, smoke PREVIEW-11 (pending) and its sign-off line, test-cases.md
    and the badge.

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

commit 7d0b5fc2bcce0f2ee96020a943c89558b95c2170
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 21:39:44 2026 +0530

    QF-01: a preview or test dial stays open on a slice click

    WEDGE_POST closed the dial after every callout pick, so in Preview as,
    the edit preview and test mode each slice tried closed the dial.
    DS.Load now writes the header's qc-preview attribute (out of combat, in
    the same Load that disarms the preview wedges; always written, false for
    a live plan), Dial.Apply passes plan.test, and WEDGE_POST closes only
    when it is not set. The snippet only reads it; the live path closes as
    before, in and out of combat.

    Tests: four test_dial_secure cases (preview pick stays open, the hub,
    ring, right/middle click and Escape still act, live closes in and out
    of combat, a live reload clears the flag) and two test_preview cases
    (a catcher pick on a Preview as, test-mode and edit-preview dial echoes
    and stays open; after /qc preview off a live pick sends and closes).
    Docs: ARCHITECTURE, module-map, data-flow, smoke PREVIEW-12 (pending),
    test-cases.md and the badge (1138).

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

commit 23e6ababf8ddc02bec36ca425708b789e81662d9
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 21:18:43 2026 +0530

    QF-00: address plan review

    Verified all seven critique points against the code and amended the spec
    and plan for each (none rejected; reasons in the plan's Plan review):
    - D1 Escape: session dismissal mark honoured by G.SyncEditPreview, since
      every render, onShow and combat end restarts the edit preview.
    - D1 start line: quiet restart after combat; per-path table.
    - D1 /qc preview off ends the edit preview via shared P.EndPreview.
    - D3 echo: SlotEcho clears ctx.coordinates; live = identity with
      Situation.Current().
    - D4b ripple: Pad_Render CHANNEL_NAME, Groups SHORT_CHANNEL, Guard
      comment and v1 note, CHANNEL1 color.
    - D4b echo matches channel index 1; perf note.
    - D4b CHAT_MSG_CHANNEL_NOTICE added; SEND-6 checks login and zone change.

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

commit 50915f0a98e827076abca06b1592aca9ded3a0b1
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 21:04:13 2026 +0530

    QF-00: spec and plan for the preview follow-ups

    The owner's 2026-10-23 requests: the preview window and start line over
    the edit preview (D1), a preview dial that stays open on a slice click
    (D2), a {coordinates} token (D3), and the prebuilts replaced with the
    owner's edits, Solo on General (/1) and coordinates in the Solo lines,
    with no migration (D4). Items QF-01..QF-06.

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

commit accc6d124dcceb39e2f3c3d40ee477d467d507f8
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 20:09:18 2026 +0530

    Record the owner's 2026-10-23 smoke pass for this run's checks

    The owner reported every in-client check this run added or amended for
    its M2 and M3 work as passed (2026-10-23). Marked passed and removed from
    Pending sign-off:

    - PREVIEW-1..8 (QC-02, QC-03)
    - PREVIEW-9 (QC-05)
    - ICON-4 (QC-06)
    - EDIT-3, EDIT-27, DIAL-9 (amended by QC-04)

    PREVIEW-10 (QC-07, a preview click prints to chat) stays pending.

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

commit accc6d124dcceb39e2f3c3d40ee477d467d507f8
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 20:09:18 2026 +0530

    Record the owner's 2026-10-23 smoke pass for this run's checks

    The owner reported every in-client check this run added or amended for
    its M2 and M3 work as passed (2026-10-23). Marked passed and removed from
    Pending sign-off:

    - PREVIEW-1..8 (QC-02, QC-03)
    - PREVIEW-9 (QC-05)
    - ICON-4 (QC-06)
    - EDIT-3, EDIT-27, DIAL-9 (amended by QC-04)

    PREVIEW-10 (QC-07, a preview click prints to chat) stays pending.

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

commit 2da5101f70afef7d14ceb5bac268085e8f3da377
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 20:00:44 2026 +0530

    QC-07: print what a preview or test click would send, tokens filled

    Owner request 2026-10-23 (inputs/addendum-04-21.png). In every preview
    flavor (Preview as, Current included, and the Groups edit preview) and
    in test mode, a click on a pad button or a dial slice prints to the
    player's own chat frame what a live press would have sent, and sends
    nothing.

    - A preview echo already existed (2026-10-20: the baked line, printed
      raw, so `%t` and `{rt8}` showed as typed and a missing {key} was
      dropped; a slot that baked no line and every test placeholder printed
      nothing). QC-07 completes it.
    - Surfaces.MarkPreview bakes each slot's echo with NS.Preview.SlotEcho:
      the callout re-baked with NS.Preview.MOCK (one table) standing in for
      a baked value missing there (<key>, <spec>, <spell N>, ...), through a
      new optional `mock` on Tokens.Expand / Bake.Bake's opts (absent: the
      send path is byte-for-byte unchanged); or, when the slot would send
      nothing, "(nothing sent: <reason>)" in PadRender.REASON_TEXT's words,
      the same strings the tooltips and the Callouts preview show.
    - Test placeholders carry NS.Preview.TestEcho: "<name> (test-mode
      placeholder: nothing sent)". Pad.ArmSlot hands the echo to a previewed
      or placeholder slot's meta only.
    - At the click, SendEngine's hook prints NS.Preview.FillEcho(echo): %t
      and %f become your target's and focus's names (new read-only
      Compat.UnitDisplayName) or <target>/<focus>; {rtN} the marker's icon,
      as chat draws it; {gN} <group N>. The slash is the baked line's
      (Channels.Prefix: the Resolver's choice under the previewed
      situation); no new channel mapping was needed.
    - The click path: the insecure OnClick hook every send button already
      carries, not an overlay. It runs after the secure handler, cannot
      cancel or taint it, and on a disarmed button (no type) the secure half
      does nothing; the echo is baked out of combat, so a click in combat
      only reads unit names and prints. No send API, no guard stamp, no echo
      awaited, no flash. Armed buttons carry no echo: live is unchanged.

    Tests first (red for the right reasons, then green): eight test_preview
    cases (a mocked token, filled target/marker/key, a group token, the
    nothing-sent line, a dial wedge, test placeholders on a pad and a dial,
    a spy on SendChatMessage, SendAddonMessage and both C_ChatInfo senders
    plus the guard and echo tracker, live armed unchanged) and a Tokens mock
    case. The review-3 solo case now expects the nothing-sent line instead
    of silence (still never the self line).

    Ripple: enUS strings, .luacheckrc (UnitExists), README (Usage and the
    0.1.0 Unreleased row; tests badge 1132), ARCHITECTURE (Preview row,
    Taint Notes), module-map, data-flow, smoke-tests PREVIEW-10 (mirrors
    SM-QC-10) and its pending sign-off line, test-cases.md regenerated.
    No CHANGELOG file exists in this repo; the README Version History is
    the changelog.

    Deviation: the mocks are bracketed token names (<target>, <spell N>)
    rather than a sample player name or a sample spell link: a fabricated
    name or link would read as real in the user's own chat frame.

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

commit 3c81ba30d147b550f1f902b3b45bc907ece3ce24
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 19:31:47 2026 +0530

    QC-RV2: refresh vendored LibKa0s from the moved local tag v1.76.0

    The local LibKa0s tag v1.76.0 moved after QC-RV's copy (9949368): to
    7e81ff7 (LK-91, step-panel labels bounded before the command column so
    a long label truncates instead of running under the slash command) and
    then to e692491 (LK-92, README only). Both payloads were replaced whole
    from `git archive v1.76.0 LibKa0s testkit` and pruned with the tag's
    tools/prune-icons.lua against the unchanged "LibKa0s icons: all" line,
    which removed nothing. diff -r against the tag copy is empty.

    Changed: libs/LibKa0s/PerfPanel.lua (PANEL_MINOR 7 -> 8) and
    libs/LibKa0s/SimPanel.lua (SIM_PANEL_MINOR stays 5 inside the
    unreleased tag). tests/_kit/ is byte-identical (kit 41). The provenance
    line already reads v1.76.0 and is kept.

    docs/revendor/2026-10-23-v1.76.0/06_REFRESH.md records the move (old ->
    new sha, files changed, gates), following the 06_REFRESH.md precedent
    of the v1.75.0 bundle; 01..05 stay frozen. No standard change.

    Gates: luacheck 0/0 in 137 files; lua tests/run.lua 1123 passed,
    0 failed, 1 skipped (test_vendor_sync green); largest authored .lua
    1499 lines.

    Refs: LK-91

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

commit 0901b8c59b4487c0be2f0c0f3098931a65b246a7
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 18:47:25 2026 +0530

    QC-06: address review — no Raise on the preview window; lift the confirms over the dial and modals

    Review finding 1 (real): PW.Sync raised the preview window on every
    show. The client's Raise lifts a frame over everything in its strata,
    and the window now shares FULLSCREEN with the popup's and the browser's
    catchers, so a `/qc preview <x>` typed with the popup open could put
    the window over the modal's dim, clickable. The Raise is dropped: the
    window keeps the client's level under MW.LEVEL. The test's frame wrapper
    now carries a mock Raise (to the top of the strata), so the level
    assertion is red under the old Sync, and a re-show is asserted too.

    Review finding 2 (real): QuickComms' confirms are Blizzard StaticPopups
    in DIALOG, the dial's strata (a level race with the hub at header
    level + 20, in the default flow: previewOnEdit shows the dial on the
    Groups page while the remove glyph asks), and under the popup's
    FULLSCREEN catcher (`/qc resetall` with the popup open). New
    ModalWindow.LiftConfirm gives a StaticPopupDialogs definition an OnShow
    that lifts its dialog to MW.CONFIRM_STRATA (FULLSCREEN_DIALOG) and an
    OnHide that hands the shared frame back in the strata it came in (kept
    in a weak table here, never written on Blizzard's frame). Ed.ConfirmDelete
    (every delete: callout, group, pad, dial) and the reset-all popup use it.
    Tests first: test_editors' new QC-06 case and test_schema's reset case.

    Ripple: PreviewWindow and ModalWindow comments, docs/ARCHITECTURE.md and
    docs/settings-panel.md, smoke ICON-4 amended (re-show and confirms, still
    pending), docs/test-cases.md regenerated, README badge 1123.

    Known red, not this item's: test_vendor_sync (LibKa0s local tag v1.76.0
    moved after QC-RV vendored it; the addendum-02 re-vendor owns it).

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

commit 69719ca436e2af41f2f340d3edd16d9d0b8ea8a9
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 18:27:15 2026 +0530

    QC-06: put the callout popup and icon browser above the preview dial

    Owner report 2026-10-23 (inputs/qc-06-callout-strata.png): with the
    preview dial open, the New callout / Edit callout dialog showed the dial
    hub's yellow dot and pointer on top of it.

    Cause (verified): the dial's secure header is DIALOG
    (modules/SendEngine.lua NewDialHeader), and the hub's front frame is
    raised to the header's level + 20 (modules/Dial_Render.lua RaiseFront).
    The popup was DIALOG too (settings/CalloutPopup.lua via ModalWindow, its
    window at LEVEL + 2..5), so inside one strata the hub's higher level won.
    The QC-02 preview window (modules/PreviewWindow.lua) was DIALOG as well.

    Fix: every QuickComms modal is now above the dial BY STRATA. The popup
    moves to FULLSCREEN (ModalWindow.STRATA). The dial's own strata is not
    touched: it is a secure header, protected in combat.

    Deviation from the item's plan (the browser to FULLSCREEN_DIALOG),
    argued: the icon browser stays in FULLSCREEN, with the popup, and sits
    above it by a band of levels of its own (ModalWindow.Build's new
    `spec.level`; the popup's base is MW.LEVEL = 10, the browser's
    MW.LEVEL_OVER = 200, far over anything the popup's nested widgets
    reach). FULLSCREEN_DIALOG is where the things that must sit over the
    browser already live: the AceGUI Dropdown pull-outs of its filter and
    set dropdowns (pull-out level = dropdown level + 1), the ColorPickerFrame
    its swatch raises (swatch level + 10), LibKa0s's shared menu and its
    Wowhead link window. Moving the browser there would put it in a level
    race with each of those (the pull-out over the grid's cells is a tie in
    practice), whereas the band only orders two frames QuickComms owns,
    with fixed levels. The resulting stacking: pads MEDIUM < settings window
    and dial screen catcher HIGH < dial DIALOG < preview window FULLSCREEN
    (client level) < popup FULLSCREEN band 10 < browser FULLSCREEN band 200
    < pull-outs, color picker, link window, menus FULLSCREEN_DIALOG.

    The preview window moves to FULLSCREEN as well (above the dial by
    strata), keeping the client's level for a child of UIParent, under a
    modal's catcher, so the popup still covers it. The share page's copy
    window (LibKa0s CopyWindow) was already FULLSCREEN.

    Tests first: test_icon_browser's new strata-order case (a STRATA_ORDER
    table) builds a dial header and asserts the popup's and the browser's
    catcher and window are above the header's strata, the pads' and the
    settings window's, and that the browser's band clears the popup's by
    >= 50 levels; the window case now expects FULLSCREEN for the popup and a
    higher level for the browser's catcher; test_preview_window asserts
    FULLSCREEN, over DIALOG by the order table, and a level under
    ModalWindow.LEVEL. All red before the fix (DIALOG over DIALOG).

    Ripple: the ModalWindow STACKING comment rewritten to say why; the
    IconBrowser, CalloutPopup and PreviewWindow comments;
    docs/settings-panel.md and docs/ARCHITECTURE.md stacking text;
    docs/smoke-tests.md ICON-4 (mirrors SM-QC-9) with its index range and
    pending sign-off line; docs/test-cases.md regenerated, README tests
    badge 1122. No CHANGELOG file exists in this repo, and the README
    Version History's Unreleased row lists features, so it is unchanged.

    Known red, not this item's: test_vendor_sync fails because the LibKa0s
    local tag v1.76.0 moved to LK-91 (7e81ff7) after QC-RV vendored it; the
    addendum-02 re-vendor owns it.

    Refs: owner report 2026-10-23 (inputs/qc-06-callout-strata.png).

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

commit d0a76072e269d7fb3f0d5794689181cda8445dd5
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 17:58:40 2026 +0530

    QC-05: draw every preview as live: no refused-bake veil on preview slots

    Owner report 2026-10-23 (inputs/qc-05-groups-preview.png): opening
    Settings -> Groups (the edit preview) faded every pad icon and laid a dark
    circle over each dial wedge's icon.

    Cause: a preview bakes against where you are. Solo in the open world
    (the edit preview, or Preview as Current) every party/smart line is
    refused, so the slot carries no line, and Pad_Render.Paint and
    Dial_Render.PaintWedge showed the refused-bake dim veil (qcDim: a 0.55
    black overlay on the button, a black disc on the wedge) over every
    disarmed preview button. Not a regression to bisect: the veil rule
    (9750c0c, d4c75e2) predates every preview flavor; Preview as with a
    synthetic grouped snapshot bakes lines and never hit it, and the edit
    preview (47f29c7) and the live Current preview (QC-01) were the first to
    bake previews against a solo snapshot.

    Fix: PadRender.Veiled(slot), shared by the pad and the dial: a previewed
    slot (slot.preview, every preview flavor) and a test placeholder never
    wear the veil; a live refused slot still does. The buttons stay disarmed
    (Pad.ArmSlot is unchanged); live rendering is unchanged. Test mode did
    not share the cause (its placeholders were already exempt).

    Tests first: test_edit_preview's QC-05 case compares every visual
    property the render path sets (icon texture, tint, alpha, desaturation,
    size; the dim, cooling, flash and lock overlays; the label; the alpha)
    on a pad button and a dial wedge between live (in a group, armed) and
    the edit preview and Preview as Current (solo, disarmed, a click sends
    nothing); red on qcDim before the fix.

    Ripple: docs/smoke-tests.md PREVIEW-9 (mirrors SM-QC-8) and its
    pending sign-off line; docs/test-cases.md regenerated, README tests
    badge 1121. No CHANGELOG file exists in this repo; the README Version
    History's Unreleased row lists features, not fixes to unreleased code,
    so it is unchanged.

    Refs: owner report 2026-10-23 (inputs/qc-05-groups-preview.png).

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

commit caa740e32f9f4cf3cc992f92371f45d495a2a34c
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 17:36:02 2026 +0530

    QC-04: document the preview window across README and the docs

    Doc ripple for the Preview as selector window (QC-01..QC-03), per
    design-qc-preview §2.4; no code change.

    - README: the Usage paragraph says bare `/qc preview` previews where you
      are in a small window whose dropdown switches the situation, End
      preview (or Escape, or the close mark) ends it, a settings-started
      preview opens the same window and outlives the settings, and the
      window keeps its dragged place. One 0.1.0 (Unreleased) bullet. No
      version bump.
    - docs/ARCHITECTURE.md: a Module Map row for modules/PreviewWindow.lua;
      the Preview.lua row amended (Current live, Off the off value, settings
      close no longer ends Preview as, the direct Sync call); the
      session-state paragraph (previewAs outlives the settings, the window's
      place saved); the TEST_MODE_CHANGED row notes the direct Sync; Slash
      Commands preview wording; Known Limitations: dial 1 can outlive the
      settings, and the two-Escape order with the settings open.
    - docs/module-map.md: row 16l amended, row 16l1 for PreviewWindow.lua,
      test rows for test_preview.lua (amended) and test_preview_window.lua.
    - docs/slash-dispatch.md: the `preview [name|off|list]` row.
    - docs/settings-panel.md: the Preview as row (Off first, opens the
      window, not ended by the settings closing).
    - docs/scope.md: the preview's own window.
    - docs/smoke-tests.md: index row and `## Preview window` section with
      PREVIEW-1..8 from SM-QC-1..8, each Result: pending; EDIT-3, EDIT-27
      and DIAL-9 amended and reset to pending "(amended 2026-10-23, QC-04:
      re-run)"; Pending sign-off lists them.

    Deviations:
    - Per the binding plan-review resolution the window's position is
      documented as persisted in the profile (previewWindow), not as a
      session-only Known Limitation; the PREVIEW index row says "the saved
      position" and PREVIEW-7 checks it across /reload.
    - docs/test-cases.md needed no edit: it is generated, and QC-01..QC-03
      already regenerated it; `lua tests/run.lua --list` matches it byte for
      byte (test_preview_window.lua 16, Total 1120).
    - docs/data-flow.md (not named by the item) still said closing the
      settings window ends Preview as; corrected with the window's flow.
    - The ARCHITECTURE Known Limitation on `qc-display` gains a clause that
      the preview window takes the first Escape under Preview as.

    Gates: lua tests/run.lua 1120 passed, 0 failed, 1 skipped; luacheck
    0/0 in 137 files; no authored .lua file above 1500 lines.

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

commit f9f4a0e3cdb956d7e892c8f5b204cfee77d9e7b1
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 17:26:12 2026 +0530

    QC-03: bare /qc preview opens the window on Current; add `list`

    settings/SlashVerbs.lua V.PreviewLines: a bare `/qc preview` now starts
    a preview of the current situation when none is on (a refused start
    prints its own line and shows nothing), or keeps the one on and syncs
    the selector window up; either way it prints `Previewing: <label>`.
    `/qc preview list` prints the old menu (`Preview as (now: ...)` and one
    line per preset) and changes nothing. An unknown name now points at
    `/qc preview list`. `off` and a preset key are unchanged. The help row
    in settings/Slash.lua names the window and the four forms; the two old
    locale keys are replaced in locales/enUS.lua.

    Tests first: test_preview's phase-3 switch case (bare starts Current,
    the menu moves to `list`, the hint names `list`), three new
    test_preview_window cases (bare opens on Current and keeps a running
    situation; bare in combat refuses with one line and no window; `list`
    changes nothing and shows no window) and test_slash's help row.

    Ripple: docs/test-cases.md regenerated and the README tests badge set to
    its Total (1120), per testing-§5; this also catches up QC-02's 13
    preview-window cases, which that commit left out of the inventory.

    Refs: OWNER_SCOPE A, B1; design-qc-preview §2.3.

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

commit 8a5406e71f235dc333894be2537d45a8f92cb939
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 17:03:58 2026 +0530

    QC-02: address review — use US spelling (GRAY/gray) in PreviewWindow

    The kit prose gate flags the British spelling from localization-§5's
    published list; the suite is green again (1117 passed, 0 failed).

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

commit c9bb690a77815aed9606a437bf60c69d6b61258c
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 16:56:21 2026 +0530

    QC-02: add the Preview as selector window, shown exactly while previewing

    New modules/PreviewWindow.lua (NS.PreviewWindow: Sync, IsShown, __frame):
    a small library-styled window (BackdropTemplate, DIALOG strata, movable,
    clamped, NS.ApplySkin, the close mark through NS.MakeCloseButton) with a
    situation dropdown (W.Dropdown, every preset, Current first, no Off) and an
    End preview button. PW.Sync is the only thing that shows or hides it:
    modules/Preview.lua calls it from announce() and from its stand-down entry,
    so every entry point (slash, settings row, the dropdown) shows it and every
    exit (off, End preview, the close mark, Escape via UISpecialFrames, test
    mode, combat, the stand-down) hides it. OnHide closes the shared dropdown
    menu (W.CloseMenu) and ends the preview only when the frame's own shown flag
    is off, so a hidden UIParent (Alt+Z) ends nothing. Degraded (LibKa0s
    absent): no window; the slash still previews.

    Position: per the plan-review resolution, the window's point persists in
    the profile (standalone-windows' persist MUST): a new defaulted profile key
    previewWindow = { point = "TOP", relPoint = "TOP", x = 0, y = -140 }
    (defaults/Profile.lua, docs/schema.md), written on drag stop, read on every
    show and re-read on PROFILE_CHANGED while shown. No schema-version step: a
    new defaulted key needs none.

    Diagnostics gains previewWindow=shown|hidden; four enUS strings; TOC line
    after modules\Preview.lua; tests/test_preview_window.lua (13 cases) and the
    diagnostics case extended.

    Deviations: the dropdown is built with the host's chevron-down and confirm
    marks (W.Dropdown opts, as DropWatcher's NS.MakeDropdown does) rather than
    the bare two-argument call; docs/schema.md gains the previewWindow row
    (QC-04's doc ripple predates the persist ruling and does not name it). The
    mock fires no OnHide on a plain Hide, so the Escape and menu cases fire
    OnHide after Hide, as test_callout_popup.lua does.

    Refs: OWNER_SCOPE A, B1, C; design-qc-preview §2.2.

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

commit 6b6a8391bc1bf495f29c90c7127c3a7a3742ecd4
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 16:40:57 2026 +0530

    QC-01: make Current a live preview and off the off value; keep it on close

    "Preview as" Current is now a start like any preset: a live preview of
    where you are (PreviewSnapshot answers Situation.Current(), so a zone
    change re-plans it, still marked and disarmed). P.OFF = "off" (with nil
    and "") is the off value: SetPreviewAs, the settings row (default "off",
    validate accepts it, Choices = Off then every preset), Schema's get
    fallback, Label(nil|off) = L["Off"] and /qc preview off. Closing the
    settings window now ends only the edit preview; Preview as outlives it,
    because the preview window (QC-02) carries the end control. The row's
    desc names that window; L["Off"] added, the old desc string removed.

    Tests first: test_preview (one switch at a time, Current follows a
    situation change, Choices, the row, the close leaves it on),
    test_edit_preview (a Preview as underneath survives the close),
    test_surfaces (end with "off"), test_slash (desc).

    Refs: OWNER_SCOPE B1, OWNER_SCOPE A (qc preview), OWNER_SCOPE C,
    design-qc-preview 2.1.

    Deviations: tests/test_schema.lua's row-default assertion also moved to
    "off" (not named in the item). The count moved 1102 -> 1104, so
    docs/test-cases.md and the README tests badge are regenerated in this
    change as testing-5 requires; the remaining docs stay with QC-04.

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

commit 77e8ff02b106c6f42bda72472bb4bb73bc37a7a0
Author: Tushar Saxena <tushar.saxena@gmail.com>
Date:   Fri Oct 23 15:53:06 2026 +0530

    QC-RV: re-vendor LibKa0s v1.76.0; standard reference checked at v2.87.0

    Re-vendor both payloads whole from the local LibKa0s tag v1.76.0
    (commit 9949368), taken with git archive, never from the working tree.
    Only Widgets.lua (13 -> 14), SimTimeline.lua (2 -> 3) and SimPanel.lua
    (4 -> 5) change bytes; tests/_kit/ is already kit 41 and byte-identical.
    All four diffs were empty after the copy, before the prune; no file was
    removed upstream.

    - CLAUDE.md: provenance line to v1.76.0; "LibKa0s icons: all (icon
      browser)." kept under it. The tag's prune-icons.lua removed nothing.
    - docs/ARCHITECTURE.md, docs/module-map.md: payload pointers to v1.76.0
      (both still said v1.75.0).
    - docs/revendor/2026-10-23-v1.76.0/: delta, candidates, decisions,
      implementation, summary. No contract blocker: Widgets 14 is additive
      and QuickComms neither calls TestStrip nor looks up Sim. Candidates
      (TestStrip kind = "sim", Sim auto-run) are listed, not adopted, per
      OWNER_SCOPE; no issue filed (M2 is non-interactive).
    - docs/revendor/2026-10-23-v1.75.1-v1.75.2/: the span bundle for the two
      tags vendored in eb18b0e and 4116872 without a bundle.

    Standard (wow-revendor-standards contract, read from the local
    WowAddonStandards checkout at v2.87.0, 2026-10-23): the TOC X-Standard
    line, the bare README badge and CLAUDE.md "Standards compliance (read
    first)" with its stop-and-flag directive are all present and current;
    no section-file renames in v2.87.0; every filename-section citation in
    the authored tree resolves inside its file's range; the dotted section
    hits are citations of the addon's own design spec, not the standard.
    No edit was needed.

    Deviations: the item's VERIFY greps v2.87.0 in the TOC, README and
    CLAUDE.md, but the installed revendor-standards contract forbids
    writing the standard version into any repo file (the reference is a
    pointer, dated only in the run report), so v2.87.0 appears in none of
    them. docs/smoke-tests.md was bare LF on disk while the index held
    CRLF (the eol gate failed before any edit here); it was re-checked out
    from the index, with no content change.

    Gates: luacheck 0/0 in 135 files; lua tests/run.lua 1102 passed,
    0 failed, 1 skipped; no authored .lua file above 1500 lines.

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