Skip to content

Portal: invalidate the split-divider hit-test cache on nested subview insertion - #8580

Merged
austinywang merged 53 commits into
manaflow-ai:mainfrom
ejc3:fix/portal-hittest-cache-invalidation
Aug 11, 2026
Merged

austinywang merged 53 commits into
manaflow-ai:mainfrom
ejc3:fix/portal-hittest-cache-invalidation

Conversation

@ejc3

@ejc3 ejc3 commented Jul 21, 2026 •

Copy link
Copy Markdown
Contributor

What you'd hit

After an NSSplitView is inserted, removed, replaced, reordered, or changed inside a nested container, terminal and browser portal hit testing can keep using stale divider regions until an unrelated geometry change refreshes the cache.

Root cause

The original cache validity key covered only the content root's direct children. Nested mutations do not change that list, and NSView.subviews is not documented as KVO-compliant. A later full-tree digest restored correctness but moved an O(view-count) traversal onto every pointer lookup, which is the latency-sensitive path this cache exists to protect.

A generation index also needs a provenance boundary: a subtree indexed as containing no split views can be detached, mutate while no window tracker can observe it, and then be reattached with a stale proof.

Fix

Both portal hosts now retain the weak identity of the root that produced their cached regions and validate that cache through one window-owned PortalViewHierarchyMutationTracker:

  • PortalSplitDividerCacheInvalidator installs one process-wide hook for every supported public NSView hierarchy mutation entrypoint: both addSubview forms, the subviews setter, both removal methods, replacement, and sortSubviews.
  • A cache miss records per-view split-presence state and the current window generation. Cache hits validate root identity, window identity, generation, root registration, and live divider regions without walking the hierarchy.
  • Mutations touching a split-bearing indexed branch, an inserted split, an unknown nonempty subtree, or a detached/cross-window subtree advance the generation and fail closed.
  • Indexed no-split state is reused only across continuous same-window moves, where every intervening hierarchy mutation passed through the same tracker. New leaves remain a constant-time fast path.
  • sortSubviews records identity order only for split-bearing indexed parents and invalidates only when the order changes. Browser interaction-layer sorting now skips already ordered subviews.
  • Existing frame, bounds, and visibility observation still handles divider geometry; structural correctness no longer depends on subview KVO.

The hook methods are resolved as a complete set before any implementation exchange, so installation cannot leave a partially hooked mutation surface.

Tests and performance proof

PortalHitTestingPerformanceTests covers nested/deep insertion, removal, replacement, content-root changes, detached root and nested-subtree mutation, hidden-to-visible transitions, moves, no-op and real sorting, and pointer-cache reuse.

  • Exact-SHA red proof at 342b48d2c18f1e44a1625c5bdf257f47bf7a3ba0: 14 tests executed; the new detached nested-subtree regression was the sole failure.
  • Exact-SHA green proof at 053695f2d7c88f8abdd6e90d9de5d3e59988f95c: all 14 tests passed.
  • Current-main exact-head revalidation at cab9967802bf8e002cf5fbf54b4b61f5b67a313e: all 14 tests passed after merging origin/main at 6089fa04d3effd27e43c5c6104a4eada62fe859f.
  • The bounded-work test compares insertion against AppKit's own identical no-cache attachment baseline across a 1,000-view prebuilt subtree and 128 active portal caches. Portal tracking adds only constant work, and cache hits do not re-walk 1,000 unrelated containers.

Project normalization, test wiring (654 files), workspace/package policy, app-host isolation/retry tests, script syntax, and git diff --check pass locally. No warning-budget or file-length-budget file is changed.

Required PR CI is waiting for the contributor fork to fast-forward from stale PR head 7346268746cff72113c85d9bc5b09f7d8cdc357b to canonical head cab9967802bf8e002cf5fbf54b4b61f5b67a313e. Current main CI independently reproduces the unrelated app-host/session failures seen in the earlier exact-branch full run; their owning repair PRs remain upstream.

Review

Canonical branch autoreview at cab9967802bf8e002cf5fbf54b4b61f5b67a313e reports no accepted/actionable findings (patch is correct, 0.9 confidence). Its merge-conflict gate against current origin/main and the cmux policy gate are clean. All three actual inline review threads are resolved.

Localization audit

No user-facing strings were added or changed.


Note

High Risk
Process-wide method swizzling on NSView/NSSplitView affects every hierarchy mutation in the app; incorrect hook or generation logic could cause stale divider hit-testing or extra cache churn on the pointer path.

Overview
Fixes stale split-divider hit-test regions when NSSplitView layout changes in nested containers, after detach/reattach, or via arranged-subview APIs—without walking the full view tree on every pointer move.

Terminal and browser portal hosts now tie cache validity to the weak cached root plus PortalSplitDividerCacheInvalidator.isHierarchyCurrent, replacing checks on direct child identity lists.

New window-owned tracking (PortalViewHierarchyMutationTracker, registration tokens, per-view node state) records split-presence at cache build and bumps a generation when divider-relevant structure changes. Process-wide AppKit hooks on NSView/NSSplitView mutation entry points feed that tracker; subview KVO for structure is removed. Detached or cross-window mutations and unknown nonempty subtrees fail closed; split-free same-window moves can stay on a fast path.

PortalSplitDividerRegion.collect now returns hierarchy nodes for indexing instead of structure-only observation lists. The browser slot view skips sortSubviews when interaction-layer priorities are already ordered.

Tests cover cache reuse, deep insertion, arranged-subview changes, content-root swaps, detached proofs, and bounded work across many caches.

Reviewed by Cursor Bugbot for commit dfe3fd7. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • Performance

    • Improved split-divider detection by reusing cached hierarchy information when the window structure remains unchanged.
    • Reduced unnecessary view hierarchy traversal and interaction-layer reordering.
  • Bug Fixes

    • Cache results now refresh reliably after view insertion, removal, replacement, reordering, detachment, or reattachment.
    • Improved handling of nested split views, content-root changes, and inactive windows.
  • Tests

    • Added comprehensive coverage for cache reuse, hierarchy mutations, deep view insertion, reordering, and detached subtrees.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026 •

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Split-divider collection now records hierarchy nodes with split-view state. Swizzled NSView mutations update generation-based registrations. Browser and terminal portals reuse caches only for current roots and registrations. Tests cover mutation, sorting, detachment, replacement, and bounded work.

Changes

Split-divider cache invalidation

Layer / File(s) Summary
Hierarchy node collection
Sources/PortalSplitDividerRegion.swift
Collection returns hierarchy nodes and propagates whether each subtree contains an NSSplitView.
Hierarchy mutation tracking
Sources/PortalViewHierarchyNodeState.swift, Sources/PortalViewHierarchyMutationRegistration.swift, Sources/PortalViewHierarchyMutationTracker.swift, Sources/PortalSplitDividerCacheInvalidator.swift
Swizzled hierarchy mutations update tracker generations and registration state. The invalidator uses tracker updates instead of direct subviews KVO.
Cache validation and invalidation
Sources/BrowserWindowPortal.swift, Sources/TerminalWindowPortal.swift, cmux.xcodeproj/project.pbxproj
Portals cache the root view and reuse regions only when the hierarchy registration is current. Interaction-layer sorting is skipped when priorities are already ordered.
Cache reuse and mutation coverage
cmuxTests/PortalHitTestingPerformanceTests.swift
Tests cover unrelated mutations, nested insertions, bounded tracker work, sorting, root replacement, detached roots, and subtree reattachment.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant WindowPortal
  participant PortalSplitDividerRegion
  participant PortalSplitDividerCacheInvalidator
  participant PortalViewHierarchyMutationTracker
  WindowPortal->>PortalSplitDividerRegion: Collect divider regions and hierarchy nodes
  WindowPortal->>PortalSplitDividerCacheInvalidator: Register root and hierarchy nodes
  PortalSplitDividerCacheInvalidator->>PortalViewHierarchyMutationTracker: Check registration generation
  PortalViewHierarchyMutationTracker-->>WindowPortal: Return current or stale status
  WindowPortal->>PortalSplitDividerRegion: Recollect regions when stale
Loading

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Cmux No Ambient Global State ❌ Error Sources/PortalViewHierarchyMutationTracker.swift:47-214 adds a private-init type whose API is mostly static funcs, creating an ambient static facade instead of a constructable owner. Move mutation behavior to a constructable per-window tracker injected by the cache invalidator; keep only minimal private AppKit bridge dispatch for hook installation.
Docstring Coverage ⚠️ Warning Docstring coverage is 3.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (23 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Swift Actor Isolation ✅ Passed All new mutable hierarchy types and the cache invalidator are explicitly @MainActor; changed region code remains MainActor-bound, with no new Sendable models, service protocols, or background UI ac...
Cmux Swift Blocking Runtime ✅ Passed The complete PR diff adds no semaphores, blocking waits, sleeps, delayed dispatch, polling, main-queue sync, or manual locks; new synchronization uses MainActor and mutation hooks.
Cmux Browser Automation Off-Main ✅ Passed The PR changes only portal split-divider caching, hierarchy tracking, project wiring, and tests; it does not modify browser socket commands, worker routing, or WebKit wait handling.
Cmux Expensive Synchronous Load ✅ Passed The production diff adds only AppKit hierarchy tracking and divider-cache logic; it adds no agent-history loader, file scan, JSON/transcript parse, syscall loop, or synchronous agent-store access.
Cmux Cache Substitution Correctness ✅ Passed The changed caches store split-divider geometry for pointer hit testing and cursor routing; they are transient UI state, not persistence, history, undo, or snapshot paths.
Cmux No Hacky Sleeps ✅ Passed The PR changes only Swift files, Swift tests, and Xcode project metadata; the rule covers non-Swift runtime code, and the added diff contains no sleep or fixed-delay primitives.
Cmux Algorithmic Complexity ✅ Passed Production changes use linear hierarchy indexing and constant-time generation checks; new scans are single-pass or bounded interaction-layer checks, with tests covering a 1,000-view subtree and 128...
Cmux Swift Concurrency ✅ Passed The PR adds no background Dispatch, Combine, completion-based async API, or fire-and-forget Task; added Swift code remains synchronous and uses AppKit callback boundaries only.
Cmux Swift @Concurrent ✅ Passed The PR diff adds no async, await, nonisolated, or @concurrent declarations. New hierarchy APIs are synchronous and explicitly @MainActor-isolated.
Cmux Swift Package Boundaries ✅ Passed The new logic is portal-specific AppKit bridge code: it uses NSView/NSWindow/NSSplitView, Objective-C associations, and method swizzling, and serves only the two portal hosts.
Cmux Swiftpm Lockfiles ✅ Passed The PR changes only Xcode source-file references; no SwiftPM package references, Package.swift, Package.resolved, .gitignore, workflow, or dependency changes are present.
Cmux Swift Logging ✅ Passed The PR adds no print, debugPrint, dump, NSLog, ad hoc output, Logger, or sensitive-data diagnostics; affected production Swift files contain no such logging calls.
Cmux User-Facing Error Privacy ✅ Passed The production diff adds no user-facing errors, alerts, or command/API output. Its only new text is an internal assertion about hook installation and contains no vendor or sensitive data.
Cmux Full Internationalization ✅ Passed The PR changes only internal AppKit cache logic and tests; it adds no user-facing text or locale/resource/message files, and the sole production literal is an internal assertionFailure.
Cmux Swiftui State Layout ✅ Passed The PR diff changes AppKit NSView/NSSplitView portal code and tests only; no new SwiftUI state, GeometryReader, lazy-row store references, or render-time state mutation appears.
Cmux Architecture Rethink ✅ Passed The AppKit swizzle is a documented required bridge; all hooks route to one @MainActor window tracker with generation/provenance invariants, and the diff adds no timing, blocking, polling, or duplic...
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed The production diff adds NSView portal/cache tracking only; it adds no standalone window or close-shortcut code. NSWindow constructions are confined to test fixtures, an allowed case.
Cmux Source Artifacts ✅ Passed All nine changed paths are intentional Swift source, tests, or Xcode project configuration; no artifact directories or generated logs, caches, recordings, or build outputs enter the diff.
Cmux No Test Or Debug Seam In Production Source ✅ Passed The production diff adds no DEBUG/test-build guard or test-shaped member. New hierarchy tracker APIs are called by production portal hooks and cache code; no test-only accessor or widened wrapper w...
Title check ✅ Passed The title clearly identifies the primary change: invalidating the split-divider hit-test cache after nested subview insertion.
Description check ✅ Passed The description clearly explains the problem, root cause, implementation, testing evidence, review status, and localization impact.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@ejc3
ejc3 force-pushed the fix/portal-hittest-cache-invalidation branch 3 times, most recently from 5b09076 to 79721ad Compare July 22, 2026 10:33
@ejc3
ejc3 marked this pull request as ready for review July 25, 2026 05:39
@greptile-apps

greptile-apps Bot commented Jul 25, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a stale split-divider hit-test cache that persisted after a split view was inserted into a nested container. The root cause was that the cache validity was checked only against the root view's direct subview list, which doesn't change on nested insertions; NSView.subviews KVO also fails to fire reliably in that scenario.

  • Introduces PortalStructureSnapshot to record the subview-identity list of every structure-observed view at collect time, and structureSnapshotsMatch to re-check those lists on each lookup — using a count check followed by a zip/allSatisfy without an intermediate array, keeping the pointer-move path allocation-free beyond the unavoidable view.subviews reads.
  • Applies the same fix to both the Terminal and Browser portals, replacing the single-root-ObjectIdentifier array with the multi-view snapshot in both splitDividerRegions() and invalidateSplitDividerRegionCache().
  • Adds PortalHitTestingPerformanceTests.terminalSplitDividerCacheRefreshesAfterNestedSubviewInsertion as the red/green regression pin, with the six existing tests remaining green.

Confidence Score: 5/5

Safe to merge — the change is narrowly scoped to cache-validity logic, all accesses remain on the main actor, and the hot-path allocation concern raised in a prior round has already been resolved.

The fix correctly expands cache-validity checks from the root view's direct subview list to the subview-identity lists of every structure-observed view, catching nested insertions that KVO misses. The pointer-move comparison path uses a count check plus a lazy zip with no intermediate array, keeping allocations to the unavoidable AppKit view.subviews reads. Both portals receive the same treatment, and a new test pins the regression. No correctness, isolation, or hot-path issues remain.

Files Needing Attention: No files require special attention.

Important Files Changed

Filename Overview
Sources/PortalSplitDividerRegion.swift Adds PortalStructureSnapshot and two static helpers; snapshot comparison uses count + zip with no intermediate ObjectIdentifier array, correctly avoids per-move heap pressure beyond unavoidable view.subviews reads.
Sources/TerminalWindowPortal.swift Replaces single-root cachedSplitDividerRootSubviewIds with cachedSplitDividerStructure and updates splitDividerRegions() / invalidateSplitDividerRegionCache() accordingly; logic is a clean one-to-one substitution.
Sources/BrowserWindowPortal.swift Identical parallel fix as TerminalWindowPortal; same substitution of root-only subview-id check with multi-view structure snapshots, no other behavioral changes.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["splitDividerRegions() called\n(pointer-move event)"] --> B{rootView available?}
    B -- No --> C["Clear cache\nReturn []"]
    B -- Yes --> D{cachedSplitDividerRegions\n& cachedSplitDividerStructure\nexist?}
    D -- No --> G
    D -- Yes --> E["structureSnapshotsMatch(structure)\nFor each observed view:\n  count check → zip ObjectIdentifier check\n(no intermediate array)"]
    E -- Match --> F["allLive(regions)?"]
    F -- Yes --> HIT["Return cached regions ✓"]
    F -- No --> G
    E -- Mismatch\n(nested insertion detected) --> G
    G["collect(in: rootView)\nTraverse view tree\nGather split divider regions\n+ structureObservedViews"] --> H["Cache regions\nSnapshot all observed views\n(root, direct children,\nsplit ancestors,\narrangedSubviews)"]
    H --> I["Update KVO observers\n(eager fast path)"]
    I --> RET["Return fresh regions"]
Loading

Reviews (3): Last reviewed commit: "portal: compare structure snapshots with..." | Re-trigger Greptile

Comment thread Sources/PortalSplitDividerRegion.swift Outdated
ejc3 added 2 commits July 24, 2026 23:36
… insertion

The split-divider region cache trusted KVO of NSView.subviews to catch structural
changes, but addSubview does not reliably emit that KVO across macOS versions, so a
split view inserted into a nested container left the cache stale and hit-testing wrong.
Replace the root-only subview-id check with a structure fingerprint over all observed
views (root, its subviews, split ancestors), recomputed on the lookup path; the KVO
observers stay as an eager fast path but correctness no longer depends on them. Same
fix in the Browser portal, which duplicated the cache.
@ejc3
ejc3 force-pushed the fix/portal-hittest-cache-invalidation branch 2 times, most recently from 23a3d19 to dfb0bad Compare July 25, 2026 07:53

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Sources/BrowserWindowPortal.swift`:
- Around line 1036-1040: Update the cached split-divider validation to include
the current root view identity in the authoritative structure record. In
Sources/BrowserWindowPortal.swift lines 1036-1040 and
Sources/TerminalWindowPortal.swift lines 374-378, pass rootView to
PortalSplitDividerRegion.structureSnapshotsMatch and require the recorded root
to match before returning cached regions; otherwise fail closed and recollect.

In `@Sources/PortalSplitDividerRegion.swift`:
- Around line 253-255: Update structureSnapshots(of:) so the structural
fingerprint includes every traversed NSView container in the hierarchy, not only
the views returned by collect; recursively snapshot each view’s subviews (or
implement an equivalent full-tree fingerprint), preserving subviewIds for each
captured container so nested split insertion invalidates cached portal
structures.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: bc2d9285-a521-43d5-9f23-51b22f82cf1c

📥 Commits

Reviewing files that changed from the base of the PR and between da8a58a and dfb0bad.

📒 Files selected for processing (3)
  • Sources/BrowserWindowPortal.swift
  • Sources/PortalSplitDividerRegion.swift
  • Sources/TerminalWindowPortal.swift

Comment thread Sources/BrowserWindowPortal.swift Outdated
Comment thread Sources/PortalSplitDividerRegion.swift Outdated
ejc3 and others added 8 commits July 30, 2026 20:15
…ment

The divider cache's structure snapshots only track the content root, its direct
children, and views that were split-related when the cache warmed up. Two gaps:
a split inserted under a container two levels deep changes no observed subview
list, and a replaced-but-still-alive content root passes validation because no
snapshot records which root it was built from. Both leave hit-testing on stale
empty regions. Failing tests first; the fix lands in the next commit.
…digest

The structure snapshots only covered the content root, its direct children,
and views that were split-related when the cache warmed, so a split inserted
under a deeper container changed no recorded subview list and the stale cache
kept winning. They also never recorded which root they were built from, so a
replaced-but-still-alive content root passed validation against the detached
tree. Replace the snapshots with a digest keyed to the root's identity that a
full-tree walk rebuilds on the lookup path: each split's identity, ancestor
chain, arranged subviews, orientation, and effective visibility. An insertion
under any container now misses the cache, while subview churn that cannot
affect dividers still reuses it, and the subviews KVO stays bounded to the
same views as before. Both portals share the digest through
PortalSplitDividerRegion.
@austinywang

Copy link
Copy Markdown
Contributor

@ejc3 The finished branch is pushed to manaflow-ai/cmux:fix/portal-hittest-cache-invalidation at exact SHA 2dfe0361282e4c79e9175448a613925aa5404afe, but PR #8580 still points to ejc3/cmux at 7346268746cff72113c85d9bc5b09f7d8cdc357b, so the PR checks and reviewers cannot see the completed fixes. Repository rules require me to push only to manaflow-ai/cmux. Please fast-forward ejc3/cmux:fix/portal-hittest-cache-invalidation to 2dfe0361282e4c79e9175448a613925aa5404afe from the canonical branch. This is a fast-forward from the current PR head. I will finish the check and review polling as soon as the PR head updates.

@austinywang

Copy link
Copy Markdown
Contributor

Follow-up: the canonical policy gate required the hierarchy hub to own its own source file. The canonical branch is now finalized at 57606a4723af010a7c4ad974ab3ab0f021711f16; this supersedes the SHA in my previous comment. Please fast-forward ejc3/cmux:fix/portal-hittest-cache-invalidation to this exact SHA from manaflow-ai/cmux:fix/portal-hittest-cache-invalidation.

@austinywang

austinywang commented Aug 7, 2026 •

Copy link
Copy Markdown
Contributor

Latest exact-SHA fork sync: the canonical branch is now at 053695f2d7c88f8abdd6e90d9de5d3e59988f95c on manaflow-ai/cmux:fix/portal-hittest-cache-invalidation. This supersedes every earlier requested SHA.

The branch includes origin/main at 3faf79585c826cd16e1830634333001b14c57684, the window-owned generation tracker, and the detached/cross-window subtree validity fix. The exact-SHA red proof is https://github.com/manaflow-ai/cmux/actions/runs/31164529106: 14 tests executed at 342b48d2c18f1e44a1625c5bdf257f47bf7a3ba0, with only terminalSplitDividerCacheRevalidatesDetachedNestedSubtree failing. The exact-SHA green proof is https://github.com/manaflow-ai/cmux/actions/runs/31165627279: all 14 tests passed at 053695f2d7c88f8abdd6e90d9de5d3e59988f95c, including the calibrated 1,000-view bounded-work coverage.

Canonical branch autoreview, the merge-conflict gate against origin/main, and the cmux policy gate are clean. Fresh full CI is running at https://github.com/manaflow-ai/cmux/actions/runs/31165694577.

@ejc3 please fast-forward ejc3/cmux:fix/portal-hittest-cache-invalidation to exact SHA 053695f2d7c88f8abdd6e90d9de5d3e59988f95c from the canonical branch so PR #8580 can run current required checks and review bots.

@austinywang

Copy link
Copy Markdown
Contributor

Current head 02aecd7c8d43b5f0caf45babc1d22a2e33354c45 supersedes the prior SHA. It now tracks all AppKit NSSplitView arranged-pane mutation APIs/property in addition to NSView hierarchy mutations, with behavior coverage for add/insert/remove/arrangesAllSubviews.

@greptile-apps review

@austinywang

Copy link
Copy Markdown
Contributor

Current head c7b568d401cd35036c75707a3e00b2248494f72a supersedes the prior SHA. Indexed subtree proofs are now invalidated in O(1) when they cross into an unindexed branch, preventing detached mutation state from being revived by a later same-window move; the exact parking/re-entry path has behavior coverage.

@greptile-apps review

Comment thread Sources/PortalViewHierarchyMutationTracker.swift
@austinywang

Copy link
Copy Markdown
Contributor

Current head be1e22b supersedes the prior review SHA. Cursor’s wrapped-detached-reentry finding is addressed at the mutation ownership boundary with exact behavior coverage; the test-only and fixed focused runs are linked on its thread. @coderabbitai review @greptile-apps review

@coderabbitai

coderabbitai Bot commented Aug 9, 2026 •

Copy link
Copy Markdown

@austinywang I will review the current PR head be1e22b14d2a0ea049c2865a230ab77a793a76e2.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@austinywang

Copy link
Copy Markdown
Contributor

Current head 0edb762 supersedes the prior review SHA. In addition to the wrapped-reentry fix, the first registration after an inactive cache interval now revokes proofs retained while mutation tracking was intentionally dormant, with a separate behavior regression/fix commit pair. @coderabbitai review @greptile-apps review

@coderabbitai

coderabbitai Bot commented Aug 9, 2026 •

Copy link
Copy Markdown

@austinywang I will review the current PR head 0edb7620e45172507c6198b2c1de66a079e6d907, including the inactive-interval registration change and its regression coverage.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@austinywang

Copy link
Copy Markdown
Contributor

CodeRabbit policy closeout for current head 0edb762: the Cmux No Ambient Global State item is consciously not changed because it misclassifies the AppKit bridge. PortalViewHierarchyMutationTracker is a real per-window owner: window, generation, weak cache registrations, and sort depth are instance state, and the owning NSWindow retains exactly that instance through an Objective-C association. The static methods are the minimal dispatch boundary called by process-wide swizzled AppKit methods to resolve the affected window-owned tracker; they hold no mutable process-wide state. Constructor-injecting a tracker into arbitrary NSView mutations is impossible without adding a second ambient registry, which would weaken the current ownership boundary. The immutable association keys are identity tokens, not runtime state. The existing Docstring Coverage warning also remains consciously rejected for the previously documented reason: these are private/internal AppKit implementation methods, while the non-obvious ownership and performance contracts are documented at type/mutation boundaries and in behavior tests.

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 779aa42. Configure here.

Comment thread cmuxTests/PortalDetachedHierarchyMutationTests.swift
@austinywang
austinywang merged commit bcfb2d7 into manaflow-ai:main Aug 11, 2026
22 of 25 checks passed
austinywang added a commit that referenced this pull request Aug 12, 2026
* Revert "Fix portal mutation tracker launch crash (#10008)"

This reverts commit a161d16.

* Revert "Portal: invalidate the split-divider hit-test cache on nested subview insertion (#8580)"

This reverts commit bcfb2d7.
azooz2003-bit added a commit that referenced this pull request Aug 13, 2026
* Hide current iOS Agent GUI

* Revert portal hierarchy mutation tracker launch crash (#10018)

* Revert "Fix portal mutation tracker launch crash (#10008)"

This reverts commit a161d16.

* Revert "Portal: invalidate the split-divider hit-test cache on nested subview insertion (#8580)"

This reverts commit bcfb2d7.

---------

Co-authored-by: Austin Wang <austinwang115@gmail.com>
@austinywang austinywang mentioned this pull request Sep 14, 2026
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.

2 participants