Repository navigation
Conversation
Checkout discovery needs to know whether a request path belongs to a known Git family before it spends a discovery slot on it. Asking Git costs a process spawn per request, which is exactly the work a path in an unknown family should never cause. MarkerCommonDir walks up to the nearest .git marker and follows it with the reader the dirty sampler already uses (a .git directory or a gitdir file, then commondir), then resolves symlinks the way `git rev-parse --path-format=absolute` reports the common dir, so both key the same family. The family-dirs tests now assert the marker read matches Git for a main checkout, a linked worktree, a subdirectory and a relative path, and that it finds nothing outside Git.
Every new-path discovery shared one daemon-wide limit of 32 jobs, and a job was allocated before its family was known. One hung mount, a burst of worktree adds in one family, or sessions opened in untracked Git directories could fill it, and from then on every new worktree in every family was refused with "capacity reached". Resolve the family from the .git marker before allocating: a path outside Git or in an unknown family returns not-found without a job or a Git spawn. A discovery already running for a path still answers it, so a binding that changes under its pending proof is still reported stale. A family runs at most 8 discoveries at once, and only its own new paths are refused while it is full; finished jobs that only retain a result do not count. The daemon-wide bound of 32 now counts only workers still running past their work deadline and refuses only families that own one, so work that ignores cancellation stays capped. The proof inside the job and its stale checks are unchanged. Refusals are a CheckoutDiscoveryPendingError naming the checkout root, the family and a reason (in_progress, draining, family_capacity, stuck_capacity). It still unwraps to ErrCheckoutMutationBusy, so every caller keeps treating it as retryable.
A discovery-pending admission refusal reported only the session cwd, so an agent or hook could not tell one pending worktree from an unavailable daemon. It now carries the checkout root as data.path, plus data.family, data.reason and state discovery_pending, and stays retryable. A daemon-level test pins the containment: with one family's discovery hung past its deadline, sessions in its primary checkout, in a directory beside an unregistered nested worktree and in an unrelated tracked repository keep answering, another family's new worktree gets its identity, and only paths inside the pending worktrees are refused. checkoutForRequestPath now states that guard.
Unfinished review fixes: build the join and draining refusals from the pending job's own root and family, leave idle authorization waits out of the family bound, and tighten two tests. The focused tests have not run on this commit; squash into the indexer and daemon commits once they pass.
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.
Every new-path checkout discovery shared one daemon-wide limit of 32 jobs, and a job was allocated before its family was known. One hung mount, a burst of worktree adds in one family, or sessions opened in untracked Git directories could fill that limit. From then on, every new worktree in every family was refused with "capacity reached". This draft bounds discovery per family, so a pending discovery is refused only inside its own worktree.
Draft status: the first three commits are done and tested. The last commit is a labelled
wip:commit holding review fixes that have not been compiled or run yet, so CI on this draft may be red.Changes
gitstate.MarkerCommonDir. It reads a checkout's family common dir from its.gitmarker, with the reader the dirty sampler already uses, and resolves symlinks the waygit rev-parse --path-format=absolutedoes. No Git process is spawned. A test asserts it matches Git for a main checkout, a linked worktree, a subdirectory and a relative path.CheckoutDiscoveryPendingErrornaming the checkout root, the family and a reason:in_progress,draining,family_capacityorstuck_capacity. It still unwraps toErrCheckoutMutationBusy, so every caller keeps treating it as retryable.data.path(the checkout root),data.family,data.reasonandstate: discovery_pending, and staysretryable: true.Tested (first three commits, at 213c320)
-raceruns pass, 108 top-level tests in all:TestResolveFamilyDirs*;TestObserveCheckoutPath*, including both new stuck-family tests and every existing binding-change subtest;internal/mcpcheckout and worktree discovery, admission, source, mutation, freshness and ref-view tests;cmd/gortexadmission, discovery and reload tests.cmd/gortexcoverage includes:TestDispatcher_PendingDiscoveryStaysInItsWorktree: one family's discovery is hung; another family's worktree, the primary checkout and an unrelated tracked repository keep answering, and only paths inside the hung worktree are refused;TestCheckoutAdmissionErrorPendingDiscoveryGolden.cmd/gortexreports 0 issues.Untested wip commit (926c2bb)
This commit holds the fixes for the last review round. None of them has been compiled or run.
data.pathfalls back to the session path when a refusal names no root.in_progress;draining.TestObserveCheckoutPathJoinedRefusalNamesItsOwnCheckoutandTestObserveCheckoutPathDeniedDiscoveriesLeaveFamilyCapacity.Once these fixes pass, they will be squashed into the indexer and daemon commits.
Not done
checkoutAdmissionErrorand the doc comment oncheckoutForRequestPath..gitentry, so such a checkout is not auto-discovered. Linked worktrees never use one.view_buildingerrors. Their text now names the root, family and reason, but structureddatais only on the daemon admission error.Refs #1033