Skip to content

fix(GenesisKit, question, claude): the hover list stays open under a resting pointer, and a decision goes to the Claude terminal in use, never to a parked one - #594

Merged
genesiscz merged 12 commits into
masterfrom
fix/2026-10-25-widget-hover-recording
Oct 26, 2026
Merged

genesiscz merged 12 commits into
masterfrom
fix/2026-10-25-widget-hover-recording

Conversation

@genesiscz

Copy link
Copy Markdown
Owner

Stacked on #582 (feat/2026-10-25-widget-followups). The hover-list and decision-delivery commits that stayed on the unified branch after the split, ported onto the reviewed widget code.

What it changes

  • The hover list no longer shrinks and grows about once a second under a resting pointer: the edge panel takes its own transparent pixels (ignoresMouseEvents = false), so a blank point during the grow is not read as the pointer leaving.
  • A Claude session resumed in two terminals gets its answers in the terminal whose registry entry moved last (by 10 minutes or more). A tie names both processes instead of a bare refusal. The registry entry's updatedAt is read for that.
  • A Claude session parked in a background job is no receiver: its socket answers, but nothing reads it, so a decision is never reported delivered there. Each skip is logged.
  • Skill notes (swift, ux, performance): why the widget and Clicky hangs reached the user, a control whose label turns fully transparent, the hover list that closed under a scrolling pointer and its real cause.

What was left out, and why

Checks

  • tsc --noEmit: exit 0.
  • bun scripts/test.ts src/question/lib/decisions/store.test.ts src/hub/lib/composer/outbox.test.ts src/ai/lib/agent-message/delivery.test.ts: 261 pass, 0 fail.
  • swift build --package-path src/macos/GenesisKit: complete. swift test --filter EdgePanel: 25 tests, 0 failures.
  • check-commits.ts: 9 commits, 0 to fix. Personal-data probe: no matches.

@eve-bot-lovinka

eve-bot-lovinka Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

🐉 eve review — ✅ APPROVE · 0 findings

→ review · run

  • Queued 03:28:14Z
  • Reading diff — 92 files
  • Building repo map
  • Analyzing (find → verify) — 0 candidates → 0 survivors · reviewed by codex/gpt-6.1-sol + codex/gpt-6-luna
  • Posting review
  • Review posted 03:34:45Z (6m 30s)

run wrun_01M5V417RE6Q0A4ZA9J39Q7FVS

Previous runs (7)
run head outcome findings took
6 b4368ba 🔁 deduped (run wrun_01M owns it) — —
5 229218d ⏭️ superseded — 4m 49s
4 05c48cc ✅ APPROVE 1 10m 32s
3 a579ca7 ✅ APPROVE 0 13m 25s
2 681f0f4 ⏳ refused — 8s
2 681f0f4 🔁 deduped (run wrun_01M owns it) — —
1 50252c0 ✅ APPROVE 0 5m 34s

@coderabbitai

coderabbitai Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

Next included review available in 8 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 3 included reviews currently available. Your 48 included PR review attempts over the past 7 days set your current allowance at 3 reviews per hour.

Learn how review limits work.

Review configuration:

Run configuration
Commits

Reviewing files that changed from the base of the PR and between dcdd6c9 and b4368ba.

Files selected for processing: 8
  • .claude/skills/performance/references/profiling.md
  • .claude/skills/swift/references/gotchas.md
  • .claude/skills/ux/references/findings.md
  • src/ai/lib/agent-message/delivery.test.ts
  • src/macos/GenesisKit/Sources/GenesisKit/Window/EdgePanelController.swift
  • src/question/lib/decisions/deliver.ts
  • src/question/lib/decisions/store.test.ts
  • src/utils/claude/peer-message.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@eve-bot-lovinka eve-bot-lovinka Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐉 eve review — ✅ Approved

50252c0 · 0 actionable findings · reviewed by codex/gpt-6.1-sol + codex/gpt-6-luna · view run ↗

Blast radius

  • deliverToSession (~) → 7 dependent(s) outside this PR: src/question/lib/decisions/send.ts, src/claude/commands/cmux/send.argv.test.ts, src/codex/commands/run.test.ts, +1 more
  • ClaudeLiveSession (Δsig) → 5 dependent(s) outside this PR: src/ai/lib/agent-message/delivery.ts
  • resolveDeliveryTarget (~) → 4 dependent(s) outside this PR: src/question/lib/inbox/drafts.ts, src/question/commands/inbox.ts
  • listClaudeLiveSessions (~) → 2 dependent(s) outside this PR: src/ai/lib/agent-message/delivery.ts
  • parseRegistryEntry (~) → 2 dependent(s) outside this PR: src/utils/claude/peer-sender.ts
  • 4 compiler diagnostic(s) on the PR head touch this diff

ℹ️ Claims vs diff — 5 claims could not be checked from the diff (c1, c2, c3, c4, c5).

@genesiscz
genesiscz force-pushed the feat/2026-10-25-widget-followups branch from e24272a to b6fb43f Compare October 26, 2026 02:12
genesiscz added a commit that referenced this pull request Oct 26, 2026
@genesiscz
genesiscz force-pushed the fix/2026-10-25-widget-hover-recording branch from 50252c0 to 681f0f4 Compare October 26, 2026 02:12
@genesiscz

Copy link
Copy Markdown
Owner Author

Review fixes 2026-10-26 03:12 from GPT-6.1 Sol judged by Claude Opus 5.5 (fable-judge)

Round 1. 0 open threads (eve 0, CodeRabbit 0). No actionable findings in the saved review bodies or PR comments; Eve approved and CodeRabbit was rate limited. Full PR self-review found 1 medium defect, fixed in a873f4451. Integration verification: not run (the lead verifies at integration).

Do not infer receiver inactivity from a missing activity timestamp (self-review, no thread)

  • Context: The picker converted a missing updatedAt to zero. When one terminal had a known timestamp and another copy had no activity timestamp, the known copy appeared to lead by decades and received the answer. Unknown activity does not prove that the other copy is idle. Non-finite or non-positive timestamps could similarly distort ranking. The same picker is used by the final delivery recheck.
  • Commit(s): a873f4451
  • Verdict: accepted
  • Code before:
    if (!second || (first.updatedAt ?? 0) - (second.updatedAt ?? 0) >= ACTIVE_RECEIVER_LEAD_MS) {
        return { peer: first, others: ranked.length - 1 };
    }
  • Code after:
    const knownActivity = ranked.every(
        (peer) => typeof peer.updatedAt === "number" && Number.isFinite(peer.updatedAt) && peer.updatedAt > 0
    );
    if (!second || (knownActivity && (first.updatedAt ?? 0) - (second.updatedAt ?? 0) >= ACTIVE_RECEIVER_LEAD_MS)) {
        return { peer: first, others: ranked.length - 1 };
    }
  • How was this fixed: All duplicate receivers must have finite, positive activity timestamps before the ten-minute lead can select one. A single receiver remains compatible with older registry entries. Ambiguity now explains unknown activity and lists the processes. Extended the existing store.test.ts with missing, zero, negative, NaN and infinite timestamps, both receiver orders, a third receiver with unknown activity, and activity becoming unknown between resolution and the consuming write boundary. Both changed files were already in the original PR diff; no new source or test files were needed. Verification: not run (the lead verifies at integration).
  • Confidence: 95%

@eve-bot-lovinka eve-bot-lovinka Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐉 eve review — 🟡 Review comments

681f0f4 · 1 actionable finding · reviewed by find codex/gpt-6.1-sol + codex/gpt-6-luna, verify codex/gpt-6-luna · view run ↗

Severity Count
🟡 Medium 1

ℹ️ Checks (advisory — CI is authoritative) — typecheck timed out (src/utils/tsconfig.json)

Blast radius

  • deliverToSession (~) → 7 dependent(s) outside this PR: src/question/lib/decisions/send.ts, src/hub/lib/composer/dispatch.ts, src/claude/commands/cmux/send.argv.test.ts, +1 more
  • ClaudeLiveSession (Δsig) → 5 dependent(s) outside this PR: src/ai/lib/agent-message/delivery.ts
  • resolveDeliveryTarget (~) → 4 dependent(s) outside this PR: src/question/lib/inbox/drafts.ts, src/question/commands/inbox.ts
  • listClaudeLiveSessions (~) → 2 dependent(s) outside this PR: src/ai/lib/agent-message/delivery.ts
  • parseRegistryEntry (~) → 2 dependent(s) outside this PR: src/utils/claude/peer-sender.ts
  • 4 compiler diagnostic(s) on the PR head touch this diff

ℹ️ Claims vs diff — Claim c5 'TypeScript type-checking completed with exit 0, the listed Bun tests passed 261 with 0 fa…' is not supported: The impact context reports type-check timed out for src/utils/tsconfig.json, contradicting the claimed completed check.
4 claims could not be checked from the diff (c1, c2, c3, c4).

Comment thread src/utils/claude/peer-message.ts
@genesiscz
genesiscz force-pushed the feat/2026-10-25-widget-followups branch from b6fb43f to cb4a002 Compare October 26, 2026 02:32
genesiscz added a commit that referenced this pull request Oct 26, 2026
genesiscz added a commit that referenced this pull request Oct 26, 2026
…try is kept as evidence, so a decision answer for it is refused instead of falling back to typing into its terminal
@genesiscz
genesiscz force-pushed the fix/2026-10-25-widget-hover-recording branch from 681f0f4 to a579ca7 Compare October 26, 2026 02:37
@genesiscz

Copy link
Copy Markdown
Owner Author

Review fixes 2026-10-26 03:37 from GPT-6.1 Sol judged by Claude Opus 5.5 (fable-judge)

Round 2. 1 unresolved thread (eve 1, CodeRabbit 0). The expanded finding is labelled Medium by its reviewer. 1 fixed locally, 0 rejected. Fixed in a579ca7; the lead ran the tests and committed.

Preserve parked-session evidence to prevent terminal fallback (eve-bot-lovinka)

  • Context: The receiver inventory discarded parked entries. Decision routing then saw no matching native receiver and fell through to an exact hook-recorded cmux surface. That old terminal could receive and submit the answer even though the conversation had moved to a background job.
  • Commit(s): a579ca765
  • Verdict: accepted
  • Code before:
    const ranked = [...peers].sort((a, b) => (b.updatedAt ?? 0) - (a.updatedAt ?? 0));
  • Code after:
    const ranked = peers.filter((peer) => !peer.parkedJobId).sort((a, b) => (b.updatedAt ?? 0) - (a.updatedAt ?? 0));
  • How was this fixed: Added listClaudeSessionInventory to preserve live parked registry entries and their parkedJobId while keeping the existing listClaudeLiveSessions API restricted to unparked message receivers. Decision routing now reads the full inventory. The shared picker excludes parked peers and returns an explicit parked refusal when none remain, preventing cmux fallback. The final delivery recheck uses the same picker, so a receiver that parks after selection is refused before a socket write. Parked entries remain logged. Extended the existing decision tests with an actual parked registry entry and a valid recorded terminal target, asserting no socket write, terminal write or fallback lookup; controls cover absent registry entries and an active companion copy. A second test covers parking before the consuming write. Extended the existing agent-message test to check preserved parked evidence and liveness filtering while ordinary receiver listing still excludes parked sessions. All four changed source/test files were already in this PR; no new source/test files or dependencies were needed. Verification:.
  • Confidence: 95%

Threads: t1 accepted

@eve-bot-lovinka eve-bot-lovinka Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐉 eve review — ✅ Approved

a579ca7 · 0 actionable findings · reviewed by find codex/gpt-6.1-sol + codex/gpt-6-luna, verify codex/gpt-6-luna · view run ↗

ℹ️ This pass reviewed the full PR diff: the incremental delta since 681f0f4b was unusable after a base-branch merge saturated GitHub's compare API (300+ files, 292 of them merge noise, list truncated).

Blast radius

  • deliverToSession (~) → 7 dependent(s) outside this PR: src/question/lib/decisions/send.ts, src/claude/commands/cmux/send.argv.test.ts, src/hub/lib/composer/dispatch.ts, +1 more
  • ClaudeLiveSession (Δsig) → 5 dependent(s) outside this PR: src/ai/lib/agent-message/delivery.ts
  • resolveDeliveryTarget (~) → 4 dependent(s) outside this PR: src/question/lib/inbox/drafts.ts, src/question/commands/inbox.ts
  • listClaudeLiveSessions (~) → 2 dependent(s) outside this PR: src/ai/lib/agent-message/delivery.ts
  • parseRegistryEntry (~) → 2 dependent(s) outside this PR: src/utils/claude/peer-sender.ts
  • 4 compiler diagnostic(s) on the PR head touch this diff

ℹ️ Claims vs diff — 5 claims could not be checked from the diff (c1, c2, c3, c4, c5).

@genesiscz
genesiscz force-pushed the feat/2026-10-25-widget-followups branch from 7d6c1da to dfd5ec5 Compare October 26, 2026 03:07
genesiscz added a commit that referenced this pull request Oct 26, 2026
genesiscz added a commit that referenced this pull request Oct 26, 2026
…try is kept as evidence, so a decision answer for it is refused instead of falling back to typing into its terminal
@genesiscz
genesiscz force-pushed the fix/2026-10-25-widget-hover-recording branch from a579ca7 to 05c48cc Compare October 26, 2026 03:08
@genesiscz
genesiscz changed the base branch from feat/2026-10-25-widget-followups to master October 26, 2026 03:19

@eve-bot-lovinka eve-bot-lovinka Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐉 eve review — 🟡 Review comments

05c48cc · 1 actionable finding · reviewed by find codex/gpt-6.1-sol + codex/gpt-6-luna, verify codex/gpt-6-luna · view run ↗

Severity Count
🟡 Medium 1

Blast radius

  • deliverToSession (~) → 7 dependent(s) outside this PR: src/question/lib/decisions/send.ts, src/hub/lib/composer/dispatch.ts, src/codex/commands/run.test.ts, +1 more
  • ClaudeLiveSession (Δsig) → 5 dependent(s) outside this PR: src/ai/lib/agent-message/delivery.ts
  • mouseEntered (~) → 5 dependent(s) outside this PR: src/macos/GenesisKit/Tests/GenesisKitTests/InstantTooltipTests.swift, src/macos/GenesisKit/Sources/GenesisKit/Style/InstantTooltip.swift, src/macos/GenesisKit/Sources/GenesisKit/Markdown/Views/MarkdownHoverPreview.swift, +2 more
  • mouseExited (~) → 5 dependent(s) outside this PR: src/macos/GenesisKit/Tests/GenesisKitTests/InstantTooltipTests.swift, src/macos/GenesisKit/Tests/GenesisKitTests/EdgePanelGeometryTests.swift, src/macos/GenesisKit/Sources/GenesisKit/Style/InstantTooltip.swift, +2 more
  • resolveDeliveryTarget (~) → 4 dependent(s) outside this PR: src/question/lib/inbox/drafts.ts, src/question/commands/inbox.ts
  • viewWillMove (+) → 3 dependent(s) outside this PR: src/macos/GenesisKit/Sources/GenesisKit/Style/InstantTooltip.swift, src/macos/GenesisKit/Sources/GenesisKit/Markdown/Views/MarkdownHoverPreview.swift, src/macos/GenesisKit/Sources/GenesisKit/Markdown/Window/MarkdownLayout.swift
  • listClaudeLiveSessions (~) → 2 dependent(s) outside this PR: src/ai/lib/agent-message/delivery.ts
  • parseRegistryEntry (~) → 2 dependent(s) outside this PR: src/utils/claude/peer-sender.ts
  • checkIgnoredExit (+) → 1 dependent(s) outside this PR: src/macos/GenesisKit/Tests/GenesisKitTests/EdgePanelGeometryTests.swift
  • +1 more changed symbol(s) with outside dependents
  • 4 compiler diagnostic(s) on the PR head touch this diff (graph truncated)

Not line-anchorable (review without the full diff context)

  • 🟡 Medium src/macos/GenesisKit/Sources/GenesisKit/Window/EdgePanelController.swift:97 · confidence 82/100 — Enable mouse-move delivery for the ignored-exit watcher: The recovery path relies on a local .mouseMoved monitor after AppKit has already consumed the tracking-area exit, but this panel never enables acceptsMouseMovedEvents (and its tracking area requests only enter/exit). AppKit does not normally deliver mouse-move events to such a window, and the global monitor excludes events destined for this application. If the pointer stays inside for the 250 ms recheck and then leaves into another GenesisTools window without dragging, neither monitor is guaranteed to run, leaving ignoredExitPending and the host's pointer-inside state stuck true. Enable mouse-move delivery while watching (and restore it on cleanup), or use a tracking mechanism that requests movement explicitly. The existing geometry test calls checkIgnoredExit() directly, so it does not exercise this event-delivery gap.

genesiscz added a commit that referenced this pull request Oct 26, 2026
…s and grows about once a second under a resting pointer: the edge panel takes its own transparent pixels (ignoresMouseEvents set to false), so a blank point during the grow no longer reads as the pointer leaving
…s answers in the one active last, and a tie names both processes instead of a bare refusal
…aude session parked in a background job: its socket answers but nothing reads it, so a parked registry entry is no receiver and each skip is logged
…user: faces without HangWatch, a guessed cause called fixed, whole-content measuring, audio started inside a key tap, and the Save draft chime
…onitor and HangWatch, which every face must start
…nores clicks until it has a content shape, and test pictures of SwiftUI come from the window server
… pointer (SwiftUI does not hit-test Liquid Glass), a session listed under its first prompt, and the loading on every session switch
…r said "left" with the pointer on the panel, not because of glass gaps (correction), and a burst of processes no watcher saw
…nel passing its transparent pixels to the window below (second correction)
…try is kept as evidence, so a decision answer for it is refused instead of falling back to typing into its terminal
@genesiscz
genesiscz force-pushed the fix/2026-10-25-widget-hover-recording branch from 229218d to b4368ba Compare October 26, 2026 03:27
@genesiscz
genesiscz merged commit b4368ba into master Oct 26, 2026
6 checks passed

@eve-bot-lovinka eve-bot-lovinka Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐉 eve review — ✅ Approved

b4368ba · 0 actionable findings · reviewed by codex/gpt-6.1-sol + codex/gpt-6-luna · view run ↗

Blast radius

  • deliverToSession (~) → 7 dependent(s) outside this PR: src/question/lib/decisions/send.ts, src/hub/lib/composer/dispatch.ts, src/codex/commands/run.test.ts, +1 more
  • ClaudeLiveSession (Δsig) → 5 dependent(s) outside this PR: src/ai/lib/agent-message/delivery.ts
  • resolveDeliveryTarget (~) → 4 dependent(s) outside this PR: src/question/lib/inbox/drafts.ts, src/question/commands/inbox.ts
  • listClaudeLiveSessions (~) → 2 dependent(s) outside this PR: src/ai/lib/agent-message/delivery.ts
  • parseRegistryEntry (~) → 2 dependent(s) outside this PR: src/utils/claude/peer-sender.ts
  • 4 compiler diagnostic(s) on the PR head touch this diff

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant