Skip to content

Event Logs workbench UI (design handoff) #823

Open
4 of 34 issues completed
Open

Description

@adamgell

Spec: docs/superpowers/specs/2026-10-08-event-logs-workbench-ui-handoff-design.md (see the section references below).
Design: Claude Design canvas "Event Log Viewer Redesign" (board exports to be attached).

Parent: #539 (Phase 3 analysis UX, Phase 4 unified timeline, Phase 7 diagnosis presentation)
Spec: docs/superpowers/specs/2026-10-08-event-logs-workbench-ui-handoff-design.md

Implements the Event Logs workbench mockups (Claude Design canvas, "Event Logs — full UI" page)
as close to the mockups as the epic invariants and design system allow. Every intentional
difference is listed in spec §4 (and D20 for v2); anything else is a defect.

Phases

Follow-ups (separate issues under #539)

Decisions (spec §13.1, recorded 2026-10-08)

Q-1 light-blue selection · Q-2 brush transient · Q-3 interim heat-map mix · Q-4 weakest-edge chains ·
Q-5/6/8/11 custom views, extra exports, delta KPIs and add-log-source in v1 · Q-7 status bar to DS now ·
Q-9/Q-10 backend follow-ups · Q-12 events 75 and 76 · Q-13 deep-link first

Invariants (from #539)

  • No causality from timestamp proximity alone: time-only relations are never chains, connectors, or counts.
  • Findings come only from the diagnosis engine.
  • Exports are redacted, except the Windows EVTX subset, which ships behind an explicit unredacted confirmation.
  • No real tenant data in fixtures.

Companion: DSRegCmd verdict-first redesign #824.

Image Image Image Image Image Image Image Image Image

Activity

  1. added
    enhancementNew feature or request
    epicTracking issue for a larger body of work
    on Oct 8, 2026
  2. 14 remaining items

  3. adamgell commented on Oct 8, 2026

    @adamgell
    OwnerAuthor

    Spec PR: #871 adds this umbrella's handoff spec under docs/superpowers/specs/, so the Spec: paths in the sub-issues resolve once it merges.


    Generated by Claude Code

  4. adamgell commented on Oct 9, 2026

    @adamgell
    OwnerAuthor

    Lane tracker (driven under the execution charter)

    Goal: every open lane reaches merge-ready. Merge-ready means all of:

    • CI green at head.
    • CodeRabbit APPROVED at the head commit (approved_at_head; GitHub's reviewDecision can show a stale approval).
    • A clean charter review posted on the PR: a cmtrace-code-review review_report with zero findings, validated by validate_agent_output.py --role code-review (main's contract). Prose fix-verification reviews iterate until nothing is open; the final JSON review runs only after CI and CodeRabbit pass.
    • The issue updated.

    Adam alone merges. Edited in place. Last update: 2026-10-17 22:54Z.

    Repo-wide CI break (2026-10-16): fix is PR #950, merge it first

    #950 at 11b9ab00: source clean in the final review, CI 16 of 16, CodeRabbit APPROVED at head. One owner ruling needed (decision 10 below). Then gh pr merge 950 -R adamgell/cmtraceopen --squash --admin. It clears rustls (0.23.46), the app's zip (9.0.4, with entry types classified exactly as zip 8.6 did after the final review caught a DOS-host symlink regression), and ignores RUSTSEC-2026-0367 to 0369 only for tauri-plugin-updater's zip 4.6.1, enforced by a [bans] wrapper entry (removal tracked in #948). After it merges, every open PR merges main.

    Owner decisions waiting on Adam

    1. CodeRabbit gate (fix(deps): clear RUSTSEC-2026-0346..0349 (rustls) and 0367..0369 (zip) #950): does a CodeRabbit run that finished with no actionable comments and posted no new review node satisfy "a new review completed after the last request" when the approval is already at head? Main recommends yes (details on the PR).
    2. CodeRabbit spending cap (the main bottleneck). About one included review an hour. Main's queue waits for the reported time instead of re-requesting. Queue: empty.
    3. Event Logs UI phase 9: Correlation chain model #838 (A): source for "Nearby, not linked". Recommendation: hide it until a producer exists. Phase 11 (the dock) draws time-only context from the feat(event-log): windowed analysis-timeline query and edge paging #907 window query, never as a link ("time only, not linked" only when every completeness condition holds); say if you want it hidden too.
    4. Event Logs UI phase 9: Correlation chain model #838 (B): finding-title join. New constraints recorded on Event Logs UI phase 9: Correlation chain model #838: one-ref findings can never title a chain; a covering contradiction vetoes a title (implemented in feat(event-log): correlation chain model (Phase 9, #838) #882); partial-cover conflict needs a ruling.
    5. Event Logs UI phase 9: Correlation chain model #838 (C): group-level Exact relations (engine change + ADR-002 addendum).
    6. DSRegCmd: Enrollments collector reports coverage gaps as zero enrollments; GUID brace format unverified #883: Enrollments collector reports gaps as zero; blocks D4 (DSRegCmd UI phase D4: Verdict banner and chips #862) and D8 (DSRegCmd UI phase D8: Status bar text #866).
    7. Event Logs UI phase 5: Filter row and chip row #832 filter row choices: seven unlisted design choices (sort and Local/UTC in More filters, Preview badge, time-window labels, quick-filter chip copy, loading readout, Clear all visibility, hover ring mechanism) with Main's recommendation on Event Logs UI phase 5: Filter row and chip row #832.
    8. Event Logs UI phase 17a: Comparison query and aggregator #849 comparison (three decisions on the issue): (a) the 2,000-event auto-load cap makes live comparison refuse on busy channels; (b) files-mode comparisons are partial by construction (recommendation: measure files mode from the capture's end); (c) the tile value versus the delta once the clock moves past the load (recommendation: mark the comparison stale, with a one-click re-compare). The lane ships honest refusals and partials until you decide.
    9. Phase 4 rulings to confirm (Main ruled so the lane can move; say if you disagree): (a) finding cards stay expanded in the Insights rail as spec 8.13 draws them, although the higher-ranked diagnosis output spec says the diagnosis card is collapsed by default; the rail is its own bounded scroll region and never displaces the grid. (b) Each finding card shows its class (Confirmed failure, Likely contributor, Contradictory evidence, Recovered) beside the confidence, an addition to 8.13 grounded in ADR-001 (severity and confidence must not stand in for class). (c) Top event ID bars and the Same ID sparkline use the singleSeries color (section 6.3); this also answers Event Logs spec: EVT chip fill vanishes on selected surfaces; Same ID sparkline has no color #895 item 2. (d) Phase 5: when the operator changes the time window, levels or Event IDs during a load and then presses Stop, the controls snap back to the criteria the loaded events were read with (no read starts after Stop, and the view never shows events under a window they were not read with). (e) Phase 4b: the grid coverage banner goes away when another visible surface discloses the gaps (the Insights tab, or the channel pane once Event Logs UI phase 8: Channel pane restyle #837 merges); it returns only when the operator has hidden both; files mode reads "{file name} not read. Findings may be incomplete."
    10. Spec 6.2 errata (feat(event-log): layout state, view bar and three-column shell (Phase 3, #829) #929): the active tab and checked toggles fall back to black or white where the brand foreground is under 4.5:1 on the selected surface (high-contrast 1.46, classic 3.75, dracula 4.35); measured table in the feat(event-log): layout state, view bar and three-column shell (Phase 3, #829) #929 PR body. Recommendation: record it in spec 6.2 the way feat(event-log): Event Logs visual token map (Phase 1, #827) #876's fallback is recorded in 6.3.
    11. fix(dsregcmd): split MDM URL presence from registry-confirmed enrollment #924 MDM visibility labels: state table and Main's recommendation (use the chip's wording on both surfaces: "No enrollment (registry)", "Enrolled (registry)") are on the PR: fix(dsregcmd): split MDM URL presence from registry-confirmed enrollment #924 (comment)
    12. Phase 19 (Event Logs UI phase 19: Add log source #853) Add log source: replace or merge? Built now as spec 8.19 reads: the added log becomes the active source and the channel pane says "Correlating: active log source only" (or "all open logs" in merged mode). The alternative opens it and merges it with the correlated log into a Log-workspace merged tab: the only way to correlate an IME log with an MSI log together (spec line 1123), but it changes the Log workspace's tabs and silently falls back to replace past the 30-snapshot cache. The literal build is a subset of the merge build, so nothing is wasted either way. Correction to Main's earlier note: issuecomment-6232603755.
    13. Spec 8.3 errata (Event Logs UI phase 5b: Field-scoped search grammar #833, two items): (a) an older build reads a saved fieldQuery hide rule as One string and hides nothing (the spec's '[Verified fallback behavior] ... remain loadable' is true, but the rule widens the view); (b) source: filters grid records only, not text logs correlated into the analysis session, because A.7b scopes evaluation to the visible records. Recommendation: record both in 8.3.
    14. Spec 8.6/8.19/A.24 "line count" (Event Logs UI phase 19: Add log source #853, also Phase 8 Event Logs UI phase 8: Channel pane restyle #837): the channel pane's "Also correlating" rows show "N entries", not lines. The session's logItems is a session-wide placed count, so it cannot give a per-file line count, and an entry is not a line for multi-line records (a 5-line CCM record is one entry). Recommendation: amend the spec to "entry count" (spec 4 entry).
    15. Spec 8.19 note copy (Event Logs UI phase 19: Add log source #853): in merged mode the pane says "Correlating: all open logs", but the Log workspace can merge a subset of open tabs, and hidden files drop out of the merged entries, so the claim can overstate. Recommendation: "Correlating: merged logs" (or name the count).
    16. Spec 8.5 histogram errata (Event Logs UI phase 6b: Event histogram with brush #835), one decision covering six readings Main ruled so the lane could move:
    • (a) The brush overlay is drawn behind the bars, at an opacity solved from the tokens: 0.6 in six themes, 0.25 in high contrast, where 60% put Error at 1.01:1.
    • (b) The x axis spans the loaded events, not the dropdown window, so unread time is never drawn as zero.
    • (c) The bucket ladder gains seconds and long day rungs, and inside the ladder's wide jumps a span charts fewer than 48 buckets (3h15m gives 40 of 5 minutes).
    • (d) The tooltip adds the zone, and the year when the chart crosses a year.
    • (e) The minimum segment is 2 px of colour plus a 1 px separator.
    • (f) The brush borders use StrokeAccessible, and the axis text uses Foreground2.
    • (g) Phase 13 (Event Logs UI phase 13: Timeline swimlanes #845, spec 8.9): the swimlane help reads "drag to select a time range", not "drag to zoom", because nothing zooms. Verbose is drawn as a hollow ring (Critical stays a circle per D21; the size ladder is the non-colour channel). The 25% high-contrast wash (the Event Logs UI phase 13: Timeline swimlanes #845 comment names 60%) is the same item as (a). Under D21, Critical (10 px) and Error (9 px) differ without colour by 1 px of size only, so the text carriers (tooltip, value text, hidden table, Details) do most of the work; decide whether D21 or the 8.9 ladder gives. Colours come from the theme object, not getComputedStyle. Lane baselines are decorative.
      Recommendation: amend 8.5 and 8.9 to match.
    1. Correlation over a narrowed view (Event Logs UI phase 10: Correlation view #839): the analysis session is built from the visible records (spec 9), so a time range or filter can turn an Ambiguous group into an Exact pair. Phase 10 discloses this in the view header. Question: should correlation run over the loaded set instead?
    2. Candidate is not engine-capturable (Event Logs UI phase 10: Correlation view #839): the real engine never fills secondary_keys, so no Candidate edge can be captured for the fixture that Event Logs UI phase 10: Correlation view #839's third comment asks for. Phase 10 proves Candidate with synthetic edges in unit tests. Decide whether that is acceptable, or whether the engine should emit secondary keys.

    Decided 2026-10-09: scenario colors to v2 (#855); "text closer to own mark" dropped; light/classic Error text #b40000 with one red-family floor; Verbose a distinct lighter neutral (nord Information near-white #f6f2ea, accepted by eye); clean review = zero-findings review_report with a re-review after dispositions.

    Decided 2026-10-10 (Adam): non-draft lane PRs are fine; the CodeRabbit gate is approved_at_head and draft state is the owner's workflow choice, not a gate (skill text aligned in a follow-up PR).

    Decided 2026-10-10 (Adam: 'your call'): when CodeRabbit holds an approval on an older commit and reviews a new head cleanly, it posts no new review; Main dismisses the stale approval so CodeRabbit records one at the head (CodeRabbit gate decision, #872 and #879).

    Merged 2026-10-10 (squash, by Adam)

    Second batch (about 00:00Z on 10-11): #880, #903, #907, #908, #913, #914, #915, #916, #920, #876, #899 (main at 810d1178; main CI green there, 15 of 15). Main's local rebuild of these on main passed tsc, vitest 2628/2628 and node 154/154 first.

    First batch: #894, #878, #885, #872, #879, #873, #881, #877, #882, #875, #904, #905, #900 (main at 56f9d8fd). Before the batch, Main rebuilt the final main locally (all 16 ready PRs squashed in order): tsc clean, vitest 2248/2248, node tests 138/138, every Rust test binary and the parser crate green.

    Event Logs UI goal (set 2026-10-10)

    Done means every v1 phase in #823's checklist through #854 is merge-ready under the charter (merging is Adam's). Critical path: #876 and #880 merged on 2026-10-11, so Phase 3 (#829) is unblocked. Phase 3 and Phase 14 were built locally on main + #880 + #876; they take main next (identical content, so their diffs shrink to the phase alone) and their PRs open after their first charter reviews.

    Phase Issue State
    3 Layout state, view bar, 3-column shell #829 PR #929 at 715be2ad: CodeRabbit APPROVED at head. The final re-review at d7c2cfc1 closed all six earlier items and found one low (a sub-pixel touch drag could persist the cap; fixed by rounding before the guard) and a PR-body nit (fixed). Blocked by the repo-wide advisory break below: CI's supply-chain step now fails on every PR. After the deps fix merges, #929 takes main, then CI and the final re-review
    4 Insights rail #830 Done locally at 90664b1c after four review rounds (the callout matches the engine's partial redaction; every stale count marked; a throttle that a tail cannot starve). Waiting for #929; the PR's final review verifies round 4
    17a Comparison query and aggregator #849 PR #951 at 736dc498: clean after eight verification rounds (anchor at issue stamps, two-sided start band, tail rows never counted with a note, zero-fill symmetric, invalidation on every change that alters what was compared). CodeRabbit next; CI's Rust check waits on #950. Adam: the #849 decisions are listed in the PR body
    14 Charts view #846 Built and reviewed through three verification rounds; last 3 lows fixed at cecdd2e1 (2803 tests). Waiting for #929 like Phase 7. Its PR opens as soon as #929 merges and it takes main, so its diff and CI cover Phase 14 only; the final review verifies round 4
    5 Filter row and chips, 7 Table restyle, 8 Channel pane, 15 Status bar, 18b EVTX subset export #832, #836, #837, #847, #852 Waiting for #929 (they take main once, then open PRs). 8: clean (zero-finding verification at 7a640e67 after five rounds: remote tail loss filed under the machine, unattributed gaps disclosed instead of k of k, backend-mirrored file and pattern rules, stale-stop origins fail closed). 5: clean (zero-finding verification at 12291d13 after seven rounds: the controls always show the criteria the loaded data was read with, or exactly one replay runs; Stop never starts a read; chained replays keep the bound on channels the operator stopped). 7 (8f722f06) and 15 (57fc97b4) done; 18b (c4367509) CI green on a dispatched run
    4b Coverage note with Elevate #831 Clean (zero-finding verification at c1e396c0): every current load gap is on at least one rendered surface and the grid banner never repeats one a surface names; claims join by the input ordinals the engine echoes (inputIndices, a small additive parser-crate field), so redacted paths still match. Waits for Phase 4, #947 and #837; small test pins and nits fold in when it takes main
    12 Grouped view #844 Clean (zero-finding verification at 5bf59887 after five rounds): every live trend span comes from a per-load read record written at commit; an empty read proves its span only for a time-only query; unread selected channels and budget gaps leave bins unknown rather than zero. Waits for #929 and Phase 7; capture and merge coordination noted for the take-main step
    #931 access-denied coverage kind #931 PR #947 at c6c4129b. First charter review: every classification site confirmed, Windows CI green on a dispatched run; its one low (no test of the Win32 capture sites) fixed with a Windows-gated test. CodeRabbit and PR CI next, then the final review. Acceptance item 1 (an unelevated live load shows Security as accessDenied) needs Adam's Windows lab; CI runners are elevated
    #935 channel-clear extraction #935 Clean (zero-finding verification at 1c24c354): behavior-preserving move of the clear workflow out of ChannelPicker.tsx (1,694 to 1,478 lines) into a hook and controls; captures byte-identical; stacked on Phase 8, lands before Phase 19
    5b Field-scoped search grammar #833 Clean (fv2 zero findings at be51f75b after four rounds): an invalid query is NOT applied, with a 400 ms settled 'Not applied' message; field values ignore Case and scope (spec 8.3; source: and data. by the same rule, recorded); each field term marks only its own column. Ten PR-body records held in final/p5b-833. Two spec 8.3 errata candidates for Adam: an older build reads a fieldQuery hide rule as One string and hides nothing; source: filters grid records only, not analysis-session text logs. Waits for Phase 5 and #929
    6a, 6b, 10, 10b, 10c, 11, 11b, 13, 16, 17b, 18a, 19, 20 #834 to #854 6a (#834): clean locally (fv2 zero findings at 92e93d27 after three fix rounds), on the local merge of Phase 4 + Phase 5b (b4f34b3c); record scope held by record identity (ids renumber on every merge), counts by reference, focus follows any chip removal; follow-ups #954, #955. 6b (#835): clean locally (fv5 zero source findings at d74d369b after six fix rounds; one shared year rule and an escalation ladder so no time label reads with equal ends; overlay opacity solved from tokens). Lab items for Adam: the Windows 100k rebucket figure and a high-contrast and largest-font check. Follow-ups #958, #959. 10 (#839): all three gates clean (GATE 1 at 6d42e4bd, GATE 2 at 6d3fac2a, GATE 3 at efacfb65); a test-comment closure (X1 6af351e2, X2 in progress, comment-only) is being confirmed before the lane is recorded clean. Correlation view, lanes, Insights card; diagnosis-summary correlation rows removed (#838 ruling 1); the fixture now carries engine-captured Exact, Ambiguous and Coverage blocked chains; every e2e replay-guard trip fails its test; follow-ups #956, #957, #960. 13 (#845): source-clean at c14219cb after one fix round (Critical is a circle per D21; hit-test against the drawn geometry; a click on a stale scene acts on nothing); only decision 15 and the capture session remain; follow-ups #961, #962 and 16 (#848) clean at 588aa5dd (fv2 zero findings after three rounds), on the 6a head (new views store with schema 1 and no migration, strict import, built-in "Enrollment triage" as a field-grammar query over three exact channels; lab: confirm DNS-Client 1014 is in System and the level of event 75). 10b (#840) GATE 1 building (merges 6b in first, to reuse its opacity solver and label rules; follow-ups #965, #966) and 11 (#842) GATE A1 building (window query with continuation loop, uncapped member index, dock default off) on the Phase 10 GATE 2 head (worktrees evtx-correlation-overview-840, evtx-correlation-dock-842). Waiting on their chains: 6b, 10, 13 and 16 need 6a; 17b needs Adam's #849 decisions; 18a and 10c need Adam's #838 decisions; 19 (#853): clean locally (fv3 zero findings at 8021373d after four fix rounds), worktree evtx-add-log-source-853 stacked on #935. Literal spec 8.19 replace model; Event Logs keeps its view only for its add flow's two triggers; a denied text-log load reopens as a text log after the elevated restart (every workspace now tickets a restorable workspace); folder adds disclose what they did not read. PR says Part of #853 (lanes wait on Phase 10). Follow-ups #952, #953

    Open lanes

    Lane PR Head Charter review CodeRabbit at head State
    D3 left nav (#861) #917 aedebf15 clean (posted) APPROVED at head Merge-ready. CI green at head (16 of 16); screenshot acceptance at the exact head; fixture follow-up #930 fixed in #924
    #869 mdm_enrolled split #924 3fdaad93 second verification: ruling 2 fully implemented; its one low (schtasks seam) fixed with CodeRabbit's thread (key row reads the diagnostic) APPROVED at head (0 unresolved); CI 16 of 16 green at head Labels wait for Adam (decision 5) plus Windows-lab evidence. Takes main after #917 and closes #930

    Merge order

    1. fix(deps): clear RUSTSEC-2026-0346..0349 (rustls) and 0367..0369 (zip) #950 (deps): clears the advisory break that fails every PR's Rust check. Needs decision 10, then gh pr merge 950 -R adamgell/cmtraceopen --squash --admin.
    2. After fix(deps): clear RUSTSEC-2026-0346..0349 (rustls) and 0367..0369 (zip) #950: feat(event-log): layout state, view bar and three-column shell (Phase 3, #829) #929 (Phase 3), fix(event-log): live channel refusals report access denied (#931) #947 (Event log live scan reports access-denied channels as record errors #931), feat(event-log): previous-period comparison query and aggregator (Phase 17a, #849) #951 (Phase 17a), feat(dsregcmd): left navigation and source card (D3, #861) #917 and fix(dsregcmd): split MDM URL presence from registry-confirmed enrollment #924 each take main, rerun CI, and get their final exact-head review. feat(dsregcmd): left navigation and source card (D3, #861) #917 was ready before the break; fix(dsregcmd): split MDM URL presence from registry-confirmed enrollment #924 follows it.
    3. After feat(event-log): layout state, view bar and three-column shell (Phase 3, #829) #929: the stacked Event Logs lanes take main and open PRs: Phases 4, 5, 7, 8, 14, 15, 18b, then 4b, 12, Extract the channel-clear workflow out of ChannelPicker.tsx #935, 5b, and 19. Phase 6a is being built on a local merge of Phase 4 and Phase 5b, and takes main once both land.

    Follow-ups filed

    Process notes

    Harness lesson

    Parallel lanes share Vite port 1420 and Playwright reuses whatever server is there, so a local e2e/screenshot run can test another worktree's code. #880 adds a globalSetup that fails fast on a foreign server; until it merges, CI's E2E job is the authority.

  5. coderabbitai commented on Oct 9, 2026

    @coderabbitai

    @adamgell #872 remains conditionally merge-ready until you decide whether to accept the approval from resolve. The tracker reports that the final delta did not receive a fresh review because of the rate limit. An APPROVED review node at head does not, by itself, establish that the final delta was reviewed.

    Thanks for the guidance on the execution charter and theme decisions. I have not independently verified current CI results or review nodes.


    ✏️ Learnings added
    Learnt from: adamgell
    URL: https://github.com/adamgell/cmtraceopen/issues/823
    
    Timestamp: 2026-10-09T13:56:43.431Z
    Learning: For adamgell/cmtraceopen umbrella issue #823, the execution charter defines merge-ready as green CI, a CodeRabbit APPROVED review node on the current head commit, a clean charter review posted on the PR, and an updated issue. An approval on an older commit does not satisfy the charter. Adam alone merges PRs.
    

    Learnt from: adamgell
    URL: https://github.com/adamgell/cmtraceopen/issues/823
    
    Timestamp: 2026-10-09T13:56:43.431Z
    Learning: For adamgell/cmtraceopen theme work under umbrella issue #823, Adam's 2026-10-09 decisions defer scenario colors to v2 issue #855, drop the "text closer to own mark" rule, set light/classic Error text to #b40000, and require one red-family floor of 15 dE00 for Critical/Error cross pairs.
    

    Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

    You are interacting with an AI system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestepicTracking issue for a larger body of workworkspaceWorkspace UI area

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions