Repository navigation
fix(core): route live Bus events before Location fanout - #52922
Open
pascalandr wants to merge 3 commits into
Open
pascalandr wants to merge 3 commits into
pascalandr wants to merge 3 commits into
Conversation
Partition live subscriptions by exact Location and event type so publishing a located event does not walk unrelated Location consumers before filtering. Preserve global recipients, publication-time Session ownership, old/new move delivery and a single ordered feed for multi-type subscriptions. Release an unused channel with its stream scope and safely reacquire a fresh channel. Add real Effect PubSub subscriber-visit regressions, channel lifetime checks, and queued typed/mixed Session move coverage. The focused Bus suite passes 67 tests; original Bus controls fail the unrelated-subscriber regressions. Core typecheck and targeted lint pass, with independent code review finding no actionable issues. Three alternating official CLI/ConPTY pairs under the same disclosed 220-loaded-Location synthetic shared-server recipe reduce Worktrees manual refresh from 3.626/12.736/13.438 s to 0.805/0.566/1.394 s. No extra native Bus observers were added. Local TUI input did not improve, and natural five-tab runs do not demonstrate a general compaction speedup. These results support reduced fanout and network-backed delay, not a complete CodeNomad freeze fix.
Contributor
|
Thanks for your contribution! This PR doesn't have a linked issue. All PRs must reference an existing issue. Please:
See CONTRIBUTING.md for details. |
Contributor
|
The following comment was made by an LLM, it may be inaccurate: |
Author
|
Issue #52921 exists and the PR body already contains Could a maintainer reconcile that label and authorize the pending fork CI? |
pascalandr
added a commit
to NeuralNomadsAI/CodeNomad
that referenced
this pull request
Oct 10, 2026
…overy (#909) ## Summary Repeated "Question and permission recovery is incomplete" warnings came from CodeNomad's own ownership checks, not from OpenCode. - **Root cause (measured on an affected Windows machine):** the native loaded-only snapshot RPC answers in about 5 ms, but each pending batch took 9–35 s and often hit the 30 s deadline. Every candidate directory spawned `git rev-parse --git-common-dir` before and after the native read, through the shared two-process Git worker. Each Windows spawn costs 50–800 ms, and the 30-second liveness pass re-checks every inventoried worktree (314 in the affected repository), so the queue stayed saturated and starved other projects. - **Git common directory without a process:** `readGitCommonDirectory` resolves the enclosing checkout from its administrative files (`.git` file/directory, `commondir`, `HEAD`/`objects`), mirroring Git discovery without crossing devices. Nested bare or separate Git directories, paths inside `.git`, Git location/discovery environment overrides and unreadable layouts defer to Git. Each call still reads current state; only in-flight reads are shared. - **Per-directory isolation:** an ownership, repository-identity or deletion-fence failure for one candidate (before or after the native read), or a rejected returned placement, reports only that directory's non-authoritative `error` instead of a 503 for the batch. A rejected placement withholds capability verification. Root/origin/connection/workspace changes, malformed or duplicate coverage, count overflow and timeouts still fail the batch. - **Diagnostics:** phase-only `Server-Timing` on every response; failures log their phase without queue contents. The root candidate reuses the root identity (7 → 2 Git identity reads). - **Warning hysteresis:** the incomplete state and known queues are retained immediately, but the toast appears only after two consecutive incomplete recoveries; one success re-arms it. ## Validation - Real-machine equivalence: **326 directories** (314 worktrees plus other repositories and nested folders) resolve in **0.5 s instead of 60–112 s** through Git, with **0 mismatches**. - Pending broker and Git preflight suites: **36/36**, including nested bare/separate-gitdir, committed HEAD/commondir markers, invalid HEAD content, dangling and backslash HEAD symlinks, and in-flight deletion regressions. The 64-directory case drops from over 40 s (already failing before this change on Windows) to under 1.5 s. - Full server suite: 958/966; the two failures are load-sensitive timing tests that pass in isolation. - UI pending suites **42/42**; rendered interruption-dock regression **14/14** with the new warning policy; CI restore-ownership command **423/423**; server and UI typecheck. - PR CI green on ebc1571 (one unrelated Windows install-fixture `EBUSY` cleanup failure passed on rerun). ## Scope This does not replace upstream [anomalyco/opencode#52922](anomalyco/opencode#52922), which addresses event fan-out across many loaded Locations. A repository that Git refuses through `safe.directory` is now accepted by the filesystem read; only administrative files are read. ## Autonomous Gatekeeper review **Completed: ZERO FINDINGS at 5077a1b, plus ZERO FINDINGS on the test-only delta to ebc1571.** A pre-PR review fixed two issues (nested bare/separate Git directory; deletion starting during final revalidation). The PR loop then ran five rounds and corrected four more divergences from Git discovery (committed HEAD/commondir markers, dangling HEAD symlinks, invalid HEAD content, backslash symlink targets), each with a regression compared against `git rev-parse`. See the PR comments for each round. ## Existing large file touched - `packages/ui/src/stores/instances.ts`: approximately 2,350 lines.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue for this PR
Closes #52921
Related to #36443; this does not add public SSE client-interest scoping.
Type of change
What does this PR do?
User impact: With many project directories loaded, compaction can leave TUI
refreshes and live updates seconds behind. CodeNomad can suffer even more:
background recovery can load many old directories, and its extra event relay
can further delay updates, making conversations appear frozen while the server
is still working.
Route live Bus events to exact Location/type channels before delivery instead
of broadcasting to unrelated Location consumers and filtering afterward.
Preserve global recipients, publication-time ownership, old/new Session moves,
mixed-type FIFO and scoped channel cleanup. No API/client changes.
How did you verify your code works?
controls fail the new unrelated-subscriber regressions.
visits, with all 780 matching/global deliveries and zero unrelated visits.
no added Bus observers, one synthetic compaction and 22 traffic sessions:
Worktrees Ctrl+R 3.626/12.736/13.438 -> 0.805/0.566/1.394 s.
graphs and did not establish a general compaction gain. This is not a claim
that the original CodeNomad freeze is resolved.
Full repository typecheck remains blocked by an inherited Windows symlink
representation in
packages/app/src/custom-elements.d.ts; targeted Core passes.Screenshots / recordings
No layout changes; measured actions used the production TUI and framebuffer.
Checklist