Skip to content

Replace ambient process state with values resolved once - #948

Open
Inok wants to merge 3 commits into
mainfrom
pavel/gh-781-temp-tree-vanishes
Open

Inok wants to merge 3 commits into
mainfrom
pavel/gh-781-temp-tree-vanishes

Conversation

@Inok

@Inok Inok commented Sep 14, 2026

Copy link
Copy Markdown
Member

Refs #781 — AI-2528

What & why

A fixture deleted from outside its owner surfaces as a DirectoryNotFoundException
wherever the victim next touches its tree, arbitrarily far from whatever removed it.
TempDir now reports that at dispose, the one place that can still name the owner —
which immediately caught orchestrator tests handing production cleanup their whole
fixture root instead of a directory under it.

Two ambient reads turned up the same way. The provider router's memo was a mutable
static that concurrent tests cleared under each other, so one test's write could
answer another's probe. The working directory was read from the process wherever it
was wanted. Both are resolved once now and injected; ambient cwd joins
BannedSymbols.txt, so a new read is a build error rather than a convention.

Where to look

The two git children behind ResolveForRepo set no working directory of their own,
so they inherited the process's. Handing the value down without also handing it to
them would have changed nothing.

One test still moves the process: a path with no directory component resolves against
nothing else.

Verification

dotnet test --solution Capacitor.slnx — 13012 tests, 12943 passed, 68 skipped, 1
failed. That failure, Installed_codex_schema_matches_the_vendored_pin, reproduces
unchanged on main (installed codex 0.154.0 against a pin taken from 0.147.0) and is
Skip.When'd on CI, which has no codex.

Rewritten assertions checked by mutation rather than by going green — pointing the
injected directory away from the repo fails 2/3 ResolveForRepoTests, 2/2 Uninstall
--project tests and 3/4 Setup acceptance tests; dropping the Cursor workspace-root
guard fails its test. The survivors are the rows whose docs already state they are
directory-independent.

dotnet publish -c Release: no IL2026/IL3050. Assembly-exclusive tests 517 → 499.

Inok and others added 3 commits September 14, 2026 22:01
A vanished TempDir surfaces as a DirectoryNotFoundException wherever the victim
next touches its tree, arbitrarily far from whatever removed it; dispose is the
one place that can still name the owner. The orchestrator tests tripped it at
once: cleanup of a standalone worktree deletes the path it is handed, and they
handed it the whole fixture rather than a directory under it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Remembering a host probe only pays off if one router outlives a call, and the
watcher re-detects every 60s for as long as it runs, so the router is a
singleton that call sites take rather than construct. A static memo was shared
across concurrent tests that each cleared it, so one test's write could answer
another's probe and its budget assertion saw no round trip.
The two git children behind ResolveForRepo set no working directory of their
own, so they inherited the process's and a test could steer them only by moving
it; handing the value down without also handing it to them would have changed
nothing. The ban covers the setter too, and one test still moves the process,
because a path with no directory component resolves against nothing else.
@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (1) 🔗 Cross-repo conflicts (1) 📜 Skill insights (0)

Grey Divider


Action required

1. Server ingest tests stop compiling 🔗 Cross-repo conflict ≡ Correctness
Description
PiImportSource adds a required GitProviderRouter constructor argument before repoDetector, but
kcap-server still constructs it with only ConfigRoot, sessionsDir, and the named detector. When
kcap-server advances its CLI submodule, both Pi import integration-test call sites fail overload
resolution in a project that directly references the CLI project.
Code

src/Capacitor.Cli/Harness/Pi/PiImportSource.cs[36]

+        GitProviderRouter                        router,
Relevance

●●● Strong

A required constructor parameter leaves directly compiling integration callers unresolved, making
this a deterministic build-breaking correctness defect.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The PR makes GitProviderRouter a required third constructor argument. kcap-server has two existing
calls that omit it, and its ingest test project directly compiles the CLI project containing this
constructor.

src/Capacitor.Cli/Harness/Pi/PiImportSource.cs[33-40]
External repo: kurrent-io/kcap-server, test/Capacitor.Server.Tests.Ingest/Integration/PiAi892ImportE2ETests.cs [57-60]
External repo: kurrent-io/kcap-server, test/Capacitor.Server.Tests.Ingest/Integration/PiAi892ImportE2ETests.cs [139-142]
External repo: kurrent-io/kcap-server, test/Capacitor.Server.Tests.Ingest/Capacitor.Server.Tests.Ingest.csproj [13-17]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Adding the required `GitProviderRouter` argument breaks existing `PiImportSource` constructions in kcap-server, whose ingest test project directly references the CLI project.

## Fix Focus Areas
- src/Capacitor.Cli/Harness/Pi/PiImportSource.cs[33-40]

## Recommended Fix
Add a backward-compatible constructor overload accepting the previous `ConfigRoot`, `sessionsDir`, and optional `repoDetector` parameters, and delegate it to the router-aware constructor. Alternatively, coordinate an update to both kcap-server call sites so they provide a `GitProviderRouter` before advancing the CLI submodule.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Global profile changes can stall 🐞 Bug ➹ Performance
Description
UseCommand.HandleAsync calls AppConfig.RepoRootOf(workdir) before selecting the --global path,
although that value is unused for a global change without --save. RepoRootOf starts `git
rev-parse, and GetGitRepoRoot blocks in ReadToEnd()` before reaching its timeout check, so a
hung git process delays a global profile change that does not need repository information.
Code

src/Capacitor.Cli/Commands/UseCommand.cs[R18-19]

+        var repoRoot = AppConfig.RepoRootOf(workdir);
+        var repoPath = global ? null : repoRoot;
Relevance

●●● Strong

Recent accepted findings favor avoiding unnecessary repository probing and eager work before
command-specific branching.

PR-#753
PR-#119

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The changed command eagerly resolves the root before branching on global; the root resolver
launches git and reads its output synchronously before applying its exit timeout. The previous
conditional expression only evaluated the repository root for non-global selection or for --save.

src/Capacitor.Cli/Commands/UseCommand.cs[15-21]
src/Capacitor.Cli.Core/Config/AppConfig.cs[51-51]
src/Capacitor.Cli.Core/Config/AppConfig.cs[180-205]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`kcap use <profile> --global` resolves a repository root even though it neither binds nor saves a repository-specific configuration. That starts an unnecessary git child process and can block the global-only operation if git does not complete.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/UseCommand.cs[18-21]

## Recommended Fix
Only call `AppConfig.RepoRootOf(workdir)` when a repository path is required: for a non-global selection or when `--save` needs a repository config location. Preserve the existing `--global --save` behavior by resolving the root in that case, while passing `null` for a plain global selection.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

3. One test manually owns a temp directory 📘 Rule violation ▣ Testability
Description
NormalizeProjectKey_is_absolute_and_collapsed creates its own TempDir instead of consuming a
[TempDir]-injected public required property. The new local joins another manually owned directory
in the same test class, so lifecycle policy remains split between method code and framework
injection.
Code

test/Capacitor.Cli.Core.Tests.Unit/Harness/Codex/CodexProjectKeyTests.cs[38]

+        using var tmp = new TempDir();
Relevance

● Weak

Recent same-rule TempDir findings were rejected despite manual fixture ownership concerns.

PR-#878
PR-#909

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 2808173 requires test classes to use a single injected [TempDir] public required
property and explicitly disallows new TempDir() calls. The changed test creates a local TempDir
directly at line 38.

Rule 2808173: Use injected [TempDir] public required property in test classes instead of manual fields
test/Capacitor.Cli.Core.Tests.Unit/Harness/Codex/CodexProjectKeyTests.cs[36-39]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`CodexProjectKeyTests` manually constructs a `TempDir`, although test classes must receive temporary directories through a public required property annotated with `[TempDir]`.

## Fix Focus Areas
- test/Capacitor.Cli.Core.Tests.Unit/Harness/Codex/CodexProjectKeyTests.cs[15-50]

## Recommended Fix
Add one `[TempDir] public required TempDir Tmp { get; init; }` property to the test class, replace the new local `TempDir` and the existing manually constructed instance with that property, and continue constructing child paths through `TempDir` helper methods.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Compliance rules (platform): 64 rules
✅ Cross-repo context — repo relationships
  Explored: repo: kurrent-io/kcap-server (sha: b2f1e8ef)
  Explored: repo: kurrent-io/cloud-meta (sha: 15782900)
Review mode: 🧠 Deep: This cross-cutting ambient-state refactor spans 161 files and 712 edit sites across command, repository-detection, harness, daemon, and integration-test paths, creating many independent wiring and behavioral opportunities for subtle defects.

Grey Divider

Tip of the day
💡 Did you know, you can ask Qodo to dismiss a finding you disagree with, with your reason on record

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment on lines +18 to +19
var repoRoot = AppConfig.RepoRootOf(workdir);
var repoPath = global ? null : repoRoot;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

2. Global profile changes can stall 🐞 Bug ➹ Performance

UseCommand.HandleAsync calls AppConfig.RepoRootOf(workdir) before selecting the --global path,
although that value is unused for a global change without --save. RepoRootOf starts `git
rev-parse, and GetGitRepoRoot blocks in ReadToEnd()` before reaching its timeout check, so a
hung git process delays a global profile change that does not need repository information.
Agent Prompt
## Issue description
`kcap use <profile> --global` resolves a repository root even though it neither binds nor saves a repository-specific configuration. That starts an unnecessary git child process and can block the global-only operation if git does not complete.

## Fix Focus Areas
- src/Capacitor.Cli/Commands/UseCommand.cs[18-21]

## Recommended Fix
Only call `AppConfig.RepoRootOf(workdir)` when a repository path is required: for a non-global selection or when `--save` needs a repository config location. Preserve the existing `--global --save` behavior by resolving the root in that case, while passing `null` for a plain global selection.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

public PiImportSource(
ConfigRoot config,
string sessionsDir,
GitProviderRouter router,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Server ingest tests stop compiling 🔗 Cross-repo conflict ≡ Correctness

PiImportSource adds a required GitProviderRouter constructor argument before repoDetector, but
kcap-server still constructs it with only ConfigRoot, sessionsDir, and the named detector. When
kcap-server advances its CLI submodule, both Pi import integration-test call sites fail overload
resolution in a project that directly references the CLI project.
Agent Prompt
## Issue description
Adding the required `GitProviderRouter` argument breaks existing `PiImportSource` constructions in kcap-server, whose ingest test project directly references the CLI project.

## Fix Focus Areas
- src/Capacitor.Cli/Harness/Pi/PiImportSource.cs[33-40]

## Recommended Fix
Add a backward-compatible constructor overload accepting the previous `ConfigRoot`, `sessionsDir`, and optional `repoDetector` parameters, and delegate it to the router-aware constructor. Alternatively, coordinate an update to both kcap-server call sites so they provide a `GitProviderRouter` before advancing the CLI submodule.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Resolve process context once and inject repository state

🐞 Bug fix ✨ Enhancement 🧪 Tests ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Resolve the working directory once and inject it throughout CLI workflows.
• Scope provider-route memoization to the DI singleton, preventing cross-test interference.
• Detect externally deleted temporary fixtures and correct tests that deleted fixture roots.
Diagram

graph TD
  A["CLI entry point"] --> B["Working directory"] --> C["DI container"] --> D["Commands and hooks"]
  C --> E["Provider router"] --> F["Repository detection"]
  D --> F
  F --> G["Git children"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Inject an environment abstraction
  • ➕ Centralizes current-directory and other process-state access behind one interface.
  • ➕ Allows tests to substitute all environment values through one dependency.
  • ➖ Introduces a broad mutable abstraction where only one immutable value is required.
  • ➖ Makes accidental late resolution possible unless the abstraction snapshots values itself.
2. Pass raw directory strings
  • ➕ Avoids introducing a dedicated value type.
  • ➕ Keeps individual constructor signatures superficially simpler.
  • ➖ Loses semantic distinction between a checkout and arbitrary paths.
  • ➖ Provides no sanctioned composition-root API for resolving process state.
3. Keep a static provider cache with synchronization
  • ➕ Requires fewer constructor and DI changes.
  • ➕ Retains process-wide memoization without an instance dependency.
  • ➖ Still exposes mutable global state to concurrent tests.
  • ➖ Requires reset coordination and preserves hidden coupling between containers.

Recommendation: Keep the PR’s immutable WorkingDirectory value and DI-owned singleton GitProviderRouter. This resolves ambient state at the composition boundary, preserves process-lifetime memoization, and gives tests isolated router instances without creating a broad environment service.

Files changed (161) +1006 / -791

Enhancement (1) +20 / -0
WorkingDirectory.csAdd the working-directory value object +20/-0

Add the working-directory value object

• Introduces an immutable checkout path resolved once from the process at the composition boundary.

src/Capacitor.Cli.Core/WorkingDirectory.cs

Bug fix (12) +109 / -69
AppConfig.csResolve repository profiles from an explicit directory +9/-6

Resolve repository profiles from an explicit directory

• Accepts WorkingDirectory for repository profile resolution and assigns its path to both git subprocesses.

src/Capacitor.Cli.Core/Config/AppConfig.cs

CommandServices.csRegister context and provider-router dependencies +6/-2

Register context and provider-router dependencies

• Passes WorkingDirectory into core context registration and registers GitProviderRouter as a singleton.

src/Capacitor.Cli/Commands/CommandServices.cs

CursorHookCommand.csUse injected context in Cursor hooks +7/-5

Use injected context in Cursor hooks

• Routes workspace repository detection through the shared router and supplies explicit memory-scope fallback context.

src/Capacitor.Cli/Commands/Harness/CursorHookCommand.cs

ImportCommand.csShare provider routing across imports +7/-6

Share provider routing across imports

• Accepts GitProviderRouter and reuses it for import sources and all repository detection paths.

src/Capacitor.Cli/Commands/ImportCommand.cs

PluginCommand.csResolve project plugin paths from injected context +5/-5

Resolve project plugin paths from injected context

• Uses WorkingDirectory for project-scoped Claude and Codex installation and removal paths.

src/Capacitor.Cli/Commands/PluginCommand.cs

SetupCommand.csPropagate resolved repository context through setup +21/-17

Propagate resolved repository context through setup

• Uses WorkingDirectory for project checks and detection, and shares GitProviderRouter across setup imports and sources.

src/Capacitor.Cli/Commands/SetupCommand.cs

UninstallCommand.csResolve project uninstall scope explicitly +5/-4

Resolve project uninstall scope explicitly

• Uses WorkingDirectory for project root discovery and passes it into plugin cleanup.

src/Capacitor.Cli/Commands/UninstallCommand.cs

WatchCommand.csShare provider routing across watcher refreshes +6/-4

Share provider routing across watcher refreshes

• Injects the singleton router into initial, evidence-derived, and periodic repository detection.

src/Capacitor.Cli/Commands/WatchCommand.cs

GitProviderRouter.csScope provider memoization to a DI instance +13/-9

Scope provider memoization to a DI instance

• Converts the static router and cache into an injectable instance, eliminating shared mutable test state.

src/Capacitor.Cli/PrDetection/GitProviderRouter.cs

RepositoryDetection.csRequire an explicit provider router +9/-8

Require an explicit provider router

• Threads GitProviderRouter through enrichment, repository detection, and provider-specific pull-request lookup.

src/Capacitor.Cli/RepositoryDetection.cs

SessionStartMemoryScopeResolver.csReplace ambient memory-scope fallback +6/-3

Replace ambient memory-scope fallback

• Falls back to injected WorkingDirectory and detects repositories through the shared router.

src/Capacitor.Cli/SessionStartMemory/SessionStartMemoryScopeResolver.cs

TempDir.csReport externally deleted temporary fixtures +15/-0

Report externally deleted temporary fixtures

• Makes disposal idempotent but throws a diagnostic error when the fixture root vanished before its owner disposed it.

test/Capacitor.Tests.Helpers/TempDir.cs

Refactor (32) +149 / -86
CapacitorContextServices.csRegister the resolved working directory +2/-0

Register the resolved working directory

• Adds WorkingDirectory to core context registration as a singleton value.

src/Capacitor.Cli.Core/CapacitorContextServices.cs

AgentCommand.csSpawn agents from the injected directory +2/-2

Spawn agents from the injected directory

• Uses WorkingDirectory when constructing agent spawn frames instead of reading process state.

src/Capacitor.Cli/Commands/AgentCommand.cs

CurateCommand.csInject repository context into curation +7/-4

Inject repository context into curation

• Uses the injected directory and shared provider router for repository validation and detection.

src/Capacitor.Cli/Commands/CurateCommand.cs

AntigravityHookCommand.csInject repository dependencies into Antigravity hooks +6/-4

Inject repository dependencies into Antigravity hooks

• Routes enrichment, exclusion, and memory-scope detection through injected router and directory values.

src/Capacitor.Cli/Commands/Harness/AntigravityHookCommand.cs

ClaudeHookCommand.csInject repository dependencies into Claude hooks +7/-6

Inject repository dependencies into Claude hooks

• Uses the shared router for enrichment and exclusion and the explicit directory for memory scope fallback.

src/Capacitor.Cli/Commands/Harness/ClaudeHookCommand.cs

CodexHookCommand.csInject repository dependencies into Codex hooks +6/-4

Inject repository dependencies into Codex hooks

• Passes the router and working directory through repository and memory-index workflows.

src/Capacitor.Cli/Commands/Harness/CodexHookCommand.cs

CopilotHookCommand.csInject repository dependencies into Copilot hooks +6/-4

Inject repository dependencies into Copilot hooks

• Uses injected repository routing and working-directory context for session handling.

src/Capacitor.Cli/Commands/Harness/CopilotHookCommand.cs

GeminiHookCommand.csInject repository dependencies into Gemini hooks +6/-4

Inject repository dependencies into Gemini hooks

• Passes injected router and directory values through enrichment, exclusion, and memory resolution.

src/Capacitor.Cli/Commands/Harness/GeminiHookCommand.cs

KiroHookCommand.csInject repository dependencies into Kiro hooks +6/-4

Inject repository dependencies into Kiro hooks

• Uses shared repository routing and explicit memory-scope directory context.

src/Capacitor.Cli/Commands/Harness/KiroHookCommand.cs

OpenCodeHookCommand.csInject repository dependencies into OpenCode hooks +6/-4

Inject repository dependencies into OpenCode hooks

• Uses the singleton router and injected directory for repository-aware session processing.

src/Capacitor.Cli/Commands/Harness/OpenCodeHookCommand.cs

PiHookCommand.csInject repository dependencies into Pi hooks +6/-4

Inject repository dependencies into Pi hooks

• Routes repository enrichment and memory scope through injected context.

src/Capacitor.Cli/Commands/Harness/PiHookCommand.cs

McpAnalyticsServer.csInject MCP analytics repository context +3/-2

Inject MCP analytics repository context

• Builds CwdRepository from the explicit working directory and shared provider router.

src/Capacitor.Cli/Commands/McpAnalyticsServer.cs

McpFlowsServer.csInject MCP flow repository context +5/-3

Inject MCP flow repository context

• Uses requester context or the injected fallback directory and shares provider routing.

src/Capacitor.Cli/Commands/McpFlowsServer.cs

McpMemoryServer.csInject MCP memory repository context +3/-2

Inject MCP memory repository context

• Constructs repository context with the resolved directory and singleton router.

src/Capacitor.Cli/Commands/McpMemoryServer.cs

McpReviewServer.csInject review repository detection context +4/-3

Inject review repository detection context

• Detects pull requests from the explicit working directory through the shared router.

src/Capacitor.Cli/Commands/McpReviewServer.cs

McpSessionsServer.csInject MCP sessions repository context +3/-2

Inject MCP sessions repository context

• Uses injected directory and provider router when creating the lazy repository resolver.

src/Capacitor.Cli/Commands/McpSessionsServer.cs

RecapCommand.csInject recap repository context +5/-3

Inject recap repository context

• Detects the current repository from the resolved working directory through the shared router.

src/Capacitor.Cli/Commands/RecapCommand.cs

SessionsCommand.csInject sessions repository context +6/-2

Inject sessions repository context

• Uses the explicit directory and provider router when deriving a default repository scope.

src/Capacitor.Cli/Commands/SessionsCommand.cs

SetupImportRunner.csShare provider routing with setup imports +5/-3

Share provider routing with setup imports

• Injects GitProviderRouter into ImportCommand and all generated import sources.

src/Capacitor.Cli/Commands/SetupImportRunner.cs

SkillsCommand.csInject skills repository context +5/-3

Inject skills repository context

• Uses the resolved directory and shared router for repository-gated skill synchronization.

src/Capacitor.Cli/Commands/SkillsCommand.cs

TranscriptFileClassification.csShare provider routing during classification +7/-3

Share provider routing during classification

• Threads GitProviderRouter through transcript classification and exclusion repository detection.

src/Capacitor.Cli/Commands/TranscriptFileClassification.cs

UseCommand.csResolve profile bindings from injected context +4/-3

Resolve profile bindings from injected context

• Derives repository roots from WorkingDirectory for profile selection and saved bindings.

src/Capacitor.Cli/Commands/UseCommand.cs

CwdRepository.csInject provider routing into lazy repository resolution +2/-2

Inject provider routing into lazy repository resolution

• Accepts GitProviderRouter and uses it for the repository’s one-time lazy detection.

src/Capacitor.Cli/CwdRepository.cs

ClaudeImportSource.csShare provider routing with Claude imports +4/-1

Share provider routing with Claude imports

• Accepts GitProviderRouter and passes it into transcript classification.

src/Capacitor.Cli/Harness/Claude/ClaudeImportSource.cs

CodexImportSource.csShare provider routing with Codex imports +4/-1

Share provider routing with Codex imports

• Accepts GitProviderRouter and passes it into transcript classification.

src/Capacitor.Cli/Harness/Codex/CodexImportSource.cs

CopilotImportSource.csInject Copilot repository routing +3/-1

Inject Copilot repository routing

• Uses the provided router in the default repository-detector delegate.

src/Capacitor.Cli/Harness/Copilot/CopilotImportSource.cs

CursorImportSource.csInject Cursor repository routing +3/-1

Inject Cursor repository routing

• Uses the provided router for default repository detection while preserving PR-free import behavior.

src/Capacitor.Cli/Harness/Cursor/CursorImportSource.cs

KiroImportSource.csInject Kiro repository routing +3/-1

Inject Kiro repository routing

• Uses the supplied router in default import repository detection.

src/Capacitor.Cli/Harness/Kiro/KiroImportSource.cs

PiImportSource.csInject Pi repository routing +3/-1

Inject Pi repository routing

• Uses the supplied router in default import repository detection.

src/Capacitor.Cli/Harness/Pi/PiImportSource.cs

Program.csResolve working directory at startup +9/-6

Resolve working directory at startup

• Snapshots the process directory once, registers it in DI, and reuses the singleton router during command dispatch.

src/Capacitor.Cli/Program.cs

RepoExclusion.csInject provider routing into repository exclusions +4/-2

Inject provider routing into repository exclusions

• Accepts GitProviderRouter for fallback repository detection during exclusion checks.

src/Capacitor.Cli/RepoExclusion.cs

SessionStartMemoryHookSupport.csInject memory-scope repository context +4/-1

Inject memory-scope repository context

• Passes the router and working directory into the default session memory scope resolver.

src/Capacitor.Cli/SessionStartMemory/SessionStartMemoryHookSupport.cs

Tests (115) +725 / -636
ResolveForRepoTests.csMake repository profile tests parallel-safe +7/-17

Make repository profile tests parallel-safe

• Injects each fixture repository directly instead of mutating the process directory, removing parallelization restrictions.

test/Capacitor.Cli.Core.Tests.Unit/Config/ResolveForRepoTests.cs

CodexConfigTomlTests.csDocument the intentional ambient-directory test +3/-1

Document the intentional ambient-directory test

• Suppresses the banned-symbol warning around the one test that specifically verifies bare relative-path resolution.

test/Capacitor.Cli.Core.Tests.Unit/Harness/Codex/CodexConfigTomlTests.cs

CodexProjectKeyTests.csUse fixture paths for project-key normalization +2/-2

Use fixture paths for project-key normalization

• Replaces current-directory path construction with a temporary fixture path.

test/Capacitor.Cli.Core.Tests.Unit/Harness/Codex/CodexProjectKeyTests.cs

BinaryProbeTests.csDocument intentional current-directory resolution +2/-0

Document intentional current-directory resolution

• Scopes the banned-symbol suppression to the relative-path behavior under test.

test/Capacitor.Cli.Core.Tests.Unit/Setup/BinaryProbeTests.cs

PtySpawnTests.csUse a stable PTY test directory +1/-1

Use a stable PTY test directory

• Uses AppContext.BaseDirectory instead of the ambient process directory for native spawn tests.

test/Capacitor.Cli.Daemon.Tests.Unit/Pty/Unix/PtySpawnTests.cs

UnixPtyProcessSpawnTests.csUse a stable Unix PTY directory +2/-2

Use a stable Unix PTY directory

• Runs spawned test processes from AppContext.BaseDirectory.

test/Capacitor.Cli.Daemon.Tests.Unit/Pty/Unix/UnixPtyProcessSpawnTests.cs

UnixSpawnerThreadTests.csUse a stable spawner test directory +1/-1

Use a stable spawner test directory

• Passes AppContext.BaseDirectory into the Unix spawner.

test/Capacitor.Cli.Daemon.Tests.Unit/Pty/Unix/UnixSpawnerThreadTests.cs

ConPtyJobObjectTests.csUse a stable ConPTY test directory +4/-4

Use a stable ConPTY test directory

• Runs Windows pseudoterminal processes from AppContext.BaseDirectory.

test/Capacitor.Cli.Daemon.Tests.Unit/Pty/Windows/ConPtyJobObjectTests.cs

AgentOrchestratorBracketedPasteTests.csKeep orchestrator cleanup below the fixture root +7/-2

Keep orchestrator cleanup below the fixture root

• Creates a dedicated worktree child so production cleanup cannot delete the owning TempDir.

test/Capacitor.Cli.Daemon.Tests.Unit/Services/AgentOrchestratorBracketedPasteTests.cs

AgentOrchestratorLocalAttachTests.csScope standalone-worktree cleanup fixtures +12/-7

Scope standalone-worktree cleanup fixtures

• Uses child worktree directories and verifies cleanup removes only the owned child, not its fixture root.

test/Capacitor.Cli.Daemon.Tests.Unit/Services/AgentOrchestratorLocalAttachTests.cs

AgentOrchestratorStopDiagnosticsTests.csProtect stop-diagnostic fixture roots +9/-4

Protect stop-diagnostic fixture roots

• Uses dedicated child worktrees for agents whose cleanup deletes standalone trees.

test/Capacitor.Cli.Daemon.Tests.Unit/Services/AgentOrchestratorStopDiagnosticsTests.cs

AgentOrchestratorVendorTests.csProtect vendor-test fixture roots +9/-6

Protect vendor-test fixture roots

• Moves standalone agent worktrees under each TempDir rather than handing cleanup the owner root.

test/Capacitor.Cli.Daemon.Tests.Unit/Services/AgentOrchestratorVendorTests.cs

LocalPermissionBridgeTests.csMake port-release verification deterministic +15/-10

Make port-release verification deterministic

• Uses a fixed non-ephemeral port and verifies the bridge actually bound it before testing shutdown and rebinding.

test/Capacitor.Cli.Daemon.Tests.Unit/Services/LocalPermissionBridgeTests.cs

AntigravitySessionStartTests.csInject Antigravity hook context +3/-2

Inject Antigravity hook context

• Supplies isolated routers and explicit working directories to integration hook instances.

test/Capacitor.Cli.Tests.Integration/AntigravitySessionStartTests.cs

AntigravitySkippedChildOverrideRoutedLoopTests.csInject import provider routing +2/-1

Inject import provider routing

• Constructs ImportCommand with an isolated GitProviderRouter.

test/Capacitor.Cli.Tests.Integration/AntigravitySkippedChildOverrideRoutedLoopTests.cs

ClaudeHookStdoutTests.csInject Claude hook context +2/-1

Inject Claude hook context

• Provides an isolated router and stable working directory to the hook under test.

test/Capacitor.Cli.Tests.Integration/ClaudeHookStdoutTests.cs

CodexSessionStartHandshakeOnPostFailureTests.csInject Codex handshake context +2/-1

Inject Codex handshake context

• Updates hook construction for explicit router and working-directory dependencies.

test/Capacitor.Cli.Tests.Integration/CodexSessionStartHandshakeOnPostFailureTests.cs

CodexSessionStartVisibilityTests.csInject Codex visibility-test context +3/-2

Inject Codex visibility-test context

• Supplies isolated routing and stable working-directory dependencies.

test/Capacitor.Cli.Tests.Integration/CodexSessionStartVisibilityTests.cs

CopilotImportSourceImportTests.csInject Copilot import routing +2/-1

Inject Copilot import routing

• Adds an isolated router while retaining the test repository-detector seam.

test/Capacitor.Cli.Tests.Integration/CopilotImportSourceImportTests.cs

CursorImportPrTests.csInject Cursor import routing +2/-1

Inject Cursor import routing

• Supplies a router alongside the controlled repository detector.

test/Capacitor.Cli.Tests.Integration/CursorImportPrTests.cs

CursorPrivatizeLifecycleFailureTests.csInject routing into Cursor privatization tests +9/-8

Inject routing into Cursor privatization tests

• Updates import sources and commands to use isolated provider routers.

test/Capacitor.Cli.Tests.Integration/CursorPrivatizeLifecycleFailureTests.cs

CursorSessionStartVisibilityTests.csInject Cursor visibility-test context +2/-1

Inject Cursor visibility-test context

• Provides the hook with an isolated router and explicit working directory.

test/Capacitor.Cli.Tests.Integration/CursorSessionStartVisibilityTests.cs

CursorSuppressedRepoImportTests.csInject suppressed-import routing +2/-1

Inject suppressed-import routing

• Adds an isolated router to the controlled Cursor import source.

test/Capacitor.Cli.Tests.Integration/CursorSuppressedRepoImportTests.cs

CursorTailingWatcherTests.csInject watcher and Cursor hook routing +4/-3

Inject watcher and Cursor hook routing

• Supplies isolated routers and explicit working directories to watcher integration fixtures.

test/Capacitor.Cli.Tests.Integration/CursorTailingWatcherTests.cs

GeminiSessionStartHandshakeOnPostFailureTests.csInject Gemini handshake context +2/-1

Inject Gemini handshake context

• Updates the Gemini hook with explicit router and working-directory dependencies.

test/Capacitor.Cli.Tests.Integration/GeminiSessionStartHandshakeOnPostFailureTests.cs

GeminiStderrShadowedOnPostFailureTests.csInject Gemini failure-test context +2/-1

Inject Gemini failure-test context

• Provides isolated repository routing and stable directory context.

test/Capacitor.Cli.Tests.Integration/GeminiStderrShadowedOnPostFailureTests.cs

ImportEndReassertTests.csInject routing into import reassertion tests +3/-1

Inject routing into import reassertion tests

• Updates import commands and transcript classification with isolated router instances.

test/Capacitor.Cli.Tests.Integration/ImportEndReassertTests.cs

KiroImportSourceImportTests.csInject Kiro import routing +2/-1

Inject Kiro import routing

• Adds an isolated router while preserving the custom detector.

test/Capacitor.Cli.Tests.Integration/KiroImportSourceImportTests.cs

PiImportSourceImportTests.csInject Pi import routing +5/-4

Inject Pi import routing

• Supplies isolated routers to Pi import sources across lifecycle and watermark scenarios.

test/Capacitor.Cli.Tests.Integration/PiImportSourceImportTests.cs

RoutedPrivatizeMembershipTests.csInject routed-import provider context +3/-2

Inject routed-import provider context

• Constructs import commands with isolated provider routers.

test/Capacitor.Cli.Tests.Integration/RoutedPrivatizeMembershipTests.cs

RoutedReplayPrivatizeTests.csInject replay-import provider context +3/-2

Inject replay-import provider context

• Updates replay import commands with isolated router instances.

test/Capacitor.Cli.Tests.Integration/RoutedReplayPrivatizeTests.cs

SessionStartCoordinationNoticesTests.csInject Claude coordination context +4/-3

Inject Claude coordination context

• Supplies explicit router and working-directory dependencies to coordination notice tests.

test/Capacitor.Cli.Tests.Integration/SessionStartCoordinationNoticesTests.cs

SessionStartMemoryRedirectTests.csInject memory redirect-test context +2/-1

Inject memory redirect-test context

• Updates the Gemini hook with isolated routing and explicit directory context.

test/Capacitor.Cli.Tests.Integration/SessionStartMemoryRedirectTests.cs

SessionStartVisibilityTests.csInject Claude visibility-test context +6/-5

Inject Claude visibility-test context

• Provides isolated routers and stable working directories across session visibility scenarios.

test/Capacitor.Cli.Tests.Integration/SessionStartVisibilityTests.cs

SpoolOutageRecoveryTests.csInject spool recovery hook context +2/-1

Inject spool recovery hook context

• Updates Claude hook construction with explicit repository dependencies.

test/Capacitor.Cli.Tests.Integration/SpoolOutageRecoveryTests.cs

WatcherHubCredentialTests.csInject watcher provider routing +2/-1

Inject watcher provider routing

• Constructs each watcher command with an isolated router.

test/Capacitor.Cli.Tests.Integration/WatcherHubCredentialTests.cs

WatcherParentExitPostTests.csInject parent-exit watcher routing +2/-1

Inject parent-exit watcher routing

• Adds an isolated GitProviderRouter to watcher fixtures.

test/Capacitor.Cli.Tests.Integration/WatcherParentExitPostTests.cs

Program.csUse stable native-host spawn directories +2/-2

Use stable native-host spawn directories

• Runs native test children from AppContext.BaseDirectory instead of ambient process state.

test/Capacitor.Cli.Tests.Unit.NativeTestHost/Program.cs

CommandContainerTests.csRegister working directory in container tests +2/-1

Register working directory in container tests

• Provides a stable WorkingDirectory when building validated command containers.

test/Capacitor.Cli.Tests.Unit/Commands/CommandContainerTests.cs

FlowsDriverSchemaConformanceTests.csInject plugin working-directory context +1/-1

Inject plugin working-directory context

• Updates plugin installation tests for the new explicit dependency.

test/Capacitor.Cli.Tests.Unit/Commands/FlowsDriverSchemaConformanceTests.cs

AntigravityHookCommandTests.csInject Antigravity unit-test context +7/-6

Inject Antigravity unit-test context

• Supplies isolated routers and stable directories to all hook instances.

test/Capacitor.Cli.Tests.Unit/Commands/Harness/AntigravityHookCommandTests.cs

ClaudeHookCommandTests.csInject Claude hook unit-test context +25/-24

Inject Claude hook unit-test context

• Updates hook fixtures and direct constructions with isolated routers and explicit working directories.

test/Capacitor.Cli.Tests.Unit/Commands/Harness/ClaudeHookCommandTests.cs

ClaudeHookInputWaitRelayTests.csInject Claude relay-test context +2/-1

Inject Claude relay-test context

• Provides repository routing and directory dependencies to the relay hook.

test/Capacitor.Cli.Tests.Unit/Commands/Harness/ClaudeHookInputWaitRelayTests.cs

CodexHookCommandTests.csInject Codex hook unit-test context +32/-31

Inject Codex hook unit-test context

• Updates all Codex hook constructions with isolated routers and explicit directories.

test/Capacitor.Cli.Tests.Unit/Commands/Harness/CodexHookCommandTests.cs

CodexHookInputWaitRelayTests.csInject Codex relay-test context +2/-1

Inject Codex relay-test context

• Supplies the new repository dependencies to relay tests.

test/Capacitor.Cli.Tests.Unit/Commands/Harness/CodexHookInputWaitRelayTests.cs

CursorHookCommandTests.csTest Cursor fallback without process mutation +33/-35

Test Cursor fallback without process mutation

• Injects hook context and rewrites the workspace-root guard test to name a repository directly instead of changing process cwd.

test/Capacitor.Cli.Tests.Unit/Commands/Harness/CursorHookCommandTests.cs

ImportChainsTests.csInject import-chain routing +2/-1

Inject import-chain routing

• Builds ImportCommand with isolated router instances.

test/Capacitor.Cli.Tests.Unit/Commands/ImportChainsTests.cs

ImportClassifyTests.csInject transcript classification routing +12/-0

Inject transcript classification routing

• Supplies a router to each classification scenario.

test/Capacitor.Cli.Tests.Unit/Commands/ImportClassifyTests.cs

ImportDiscoveryAgeTests.csInject routing into discovery-age sources +9/-8

Inject routing into discovery-age sources

• Updates repository-aware import source constructors with isolated routers.

test/Capacitor.Cli.Tests.Unit/Commands/ImportDiscoveryAgeTests.cs

ImportResolveReposSubSessionTests.csInject sub-session repository routing +2/-1

Inject sub-session repository routing

• Constructs ImportCommand with an isolated provider router.

test/Capacitor.Cli.Tests.Unit/Commands/ImportResolveReposSubSessionTests.cs

ImportSkipTitleTests.csInject skip-title import routing +3/-2

Inject skip-title import routing

• Adds isolated routers to the command and Claude import source.

test/Capacitor.Cli.Tests.Unit/Commands/ImportSkipTitleTests.cs

ImportVendorSelectionOutputTests.csInject vendor-selection routing +2/-1

Inject vendor-selection routing

• Updates the import command fixture with an isolated router.

test/Capacitor.Cli.Tests.Unit/Commands/ImportVendorSelectionOutputTests.cs

ImportVisibilityTests.csInject routing across visibility imports +53/-52

Inject routing across visibility imports

• Updates commands and repository-aware import sources throughout visibility scenarios.

test/Capacitor.Cli.Tests.Unit/Commands/ImportVisibilityTests.cs

McpAnalyticsServerTests.csInject analytics server context +3/-1

Inject analytics server context

• Provides a router and stable working directory to the MCP server fixture.

test/Capacitor.Cli.Tests.Unit/Commands/McpAnalyticsServerTests.cs

McpFlowsServerReviewerVendorsTests.csInject flow reviewer server context +2/-1

Inject flow reviewer server context

• Updates the MCP flow server fixture with explicit repository dependencies.

test/Capacitor.Cli.Tests.Unit/Commands/McpFlowsServerReviewerVendorsTests.cs

McpFlowsServerSettlementRetryTests.csInject settlement server context +3/-1

Inject settlement server context

• Provides isolated routing and stable directory context.

test/Capacitor.Cli.Tests.Unit/Commands/McpFlowsServerSettlementRetryTests.cs

McpFlowsServerTests.csInject flow server context +3/-1

Inject flow server context

• Updates the shared server fixture for explicit repository dependencies.

test/Capacitor.Cli.Tests.Unit/Commands/McpFlowsServerTests.cs

McpFlowsServerVendorOverrideTests.csInject vendor-override server context +3/-1

Inject vendor-override server context

• Supplies a router and working directory to the MCP flow server.

test/Capacitor.Cli.Tests.Unit/Commands/McpFlowsServerVendorOverrideTests.cs

ParticipantUnreachableRetryTests.csInject participant retry server context +3/-1

Inject participant retry server context

• Updates the flow server fixture with explicit repository context.

test/Capacitor.Cli.Tests.Unit/Commands/ParticipantUnreachableRetryTests.cs

PluginCommandAntigravityTests.csInject Antigravity plugin directory context +7/-6

Inject Antigravity plugin directory context

• Provides a stable WorkingDirectory to plugin install and removal tests.

test/Capacitor.Cli.Tests.Unit/Commands/PluginCommandAntigravityTests.cs

PluginCommandClaudeTests.csInject Claude plugin directory context +7/-7

Inject Claude plugin directory context

• Updates Claude plugin tests for the explicit working-directory dependency.

test/Capacitor.Cli.Tests.Unit/Commands/PluginCommandClaudeTests.cs

PluginCommandCodexTests.csInject Codex plugin directory context +12/-12

Inject Codex plugin directory context

• Provides stable directory context to Codex plugin installation and removal tests.

test/Capacitor.Cli.Tests.Unit/Commands/PluginCommandCodexTests.cs

PluginCommandCopilotTests.csInject Copilot plugin directory context +12/-11

Inject Copilot plugin directory context

• Updates Copilot plugin tests with a stable WorkingDirectory.

test/Capacitor.Cli.Tests.Unit/Commands/PluginCommandCopilotTests.cs

PluginCommandCursorTests.csInject Cursor plugin directory context +8/-8

Inject Cursor plugin directory context

• Supplies explicit working-directory context to Cursor plugin tests.

test/Capacitor.Cli.Tests.Unit/Commands/PluginCommandCursorTests.cs

PluginCommandGeminiTests.csInject Gemini plugin directory context +14/-13

Inject Gemini plugin directory context

• Updates Gemini plugin lifecycle tests with a stable WorkingDirectory.

test/Capacitor.Cli.Tests.Unit/Commands/PluginCommandGeminiTests.cs

PluginCommandKiroTests.csInject Kiro plugin directory context +7/-6

Inject Kiro plugin directory context

• Provides explicit directory context to Kiro plugin tests.

test/Capacitor.Cli.Tests.Unit/Commands/PluginCommandKiroTests.cs

PluginCommandOpenCodeTests.csInject OpenCode plugin directory context +9/-9

Inject OpenCode plugin directory context

• Updates OpenCode plugin lifecycle tests with a stable directory value.

test/Capacitor.Cli.Tests.Unit/Commands/PluginCommandOpenCodeTests.cs

PluginCommandPiTests.csInject Pi plugin directory context +10/-9

Inject Pi plugin directory context

• Supplies WorkingDirectory to Pi extension and integration tests.

test/Capacitor.Cli.Tests.Unit/Commands/PluginCommandPiTests.cs

PluginCommandSkillsTests.csInject skills plugin directory context +9/-9

Inject skills plugin directory context

• Updates shared skill installation and removal tests with explicit directory context.

test/Capacitor.Cli.Tests.Unit/Commands/PluginCommandSkillsTests.cs

PluginCommandStaleAgentTests.csInject stale-agent plugin context +5/-4

Inject stale-agent plugin context

• Provides a stable WorkingDirectory to Kiro stale-agent scenarios.

test/Capacitor.Cli.Tests.Unit/Commands/PluginCommandStaleAgentTests.cs

PluginCommandVendorSkillsTests.csInject vendor-skill plugin context +10/-10

Inject vendor-skill plugin context

• Updates cross-vendor skill lifecycle tests with explicit directory context.

test/Capacitor.Cli.Tests.Unit/Commands/PluginCommandVendorSkillsTests.cs

ReplayChildContentCapabilityTests.csInject routing into capability sources +7/-6

Inject routing into capability sources

• Supplies isolated routers to every repository-aware import source.

test/Capacitor.Cli.Tests.Unit/Commands/ReplayChildContentCapabilityTests.cs

ReviewerVendorFallbackTests.csInject reviewer fallback server context +3/-1

Inject reviewer fallback server context

• Updates the MCP flow server fixture with explicit repository dependencies.

test/Capacitor.Cli.Tests.Unit/Commands/ReviewerVendorFallbackTests.cs

SetupChosenServerTests.csInject setup chosen-server context +2/-1

Inject setup chosen-server context

• Provides the setup command with isolated routing and stable directory values.

test/Capacitor.Cli.Tests.Unit/Commands/SetupChosenServerTests.cs

SetupCommandTests.csTest setup without changing process cwd +23/-33

Test setup without changing process cwd

• Injects fixture repository paths into SetupCommand and removes process-directory mutation from end-to-end fixtures.

test/Capacitor.Cli.Tests.Unit/Commands/SetupCommandTests.cs

SetupFacadeParityTests.csInject setup facade context +2/-1

Inject setup facade context

• Updates SetupCommand construction with explicit router and directory dependencies.

test/Capacitor.Cli.Tests.Unit/Commands/SetupFacadeParityTests.cs

SetupImportLaneTests.csInject routing into setup import lanes +7/-6

Inject routing into setup import lanes

• Updates setup lanes, import commands, source construction, and filtering tests with isolated routers.

test/Capacitor.Cli.Tests.Unit/Commands/SetupImportLaneTests.cs

ShutdownTranscriptSpoolTests.csInject shutdown watcher routing +2/-1

Inject shutdown watcher routing

• Constructs WatchCommand with an isolated provider router.

test/Capacitor.Cli.Tests.Unit/Commands/ShutdownTranscriptSpoolTests.cs

SqliteNativeResolverTests.csPreserve the temporary mirror fixture +2/-3

Preserve the temporary mirror fixture

• Uses a nonexistent child path to prove cache-only behavior instead of deleting the owning TempDir.

test/Capacitor.Cli.Tests.Unit/Commands/SqliteNativeResolverTests.cs

StatusWaitArgumentTests.csInject status server context +3/-1

Inject status server context

• Updates the MCP flow fixture with explicit routing and directory context.

test/Capacitor.Cli.Tests.Unit/Commands/StatusWaitArgumentTests.cs

ToolCallBudgetTests.csInject tool-call server context +3/-1

Inject tool-call server context

• Provides the MCP flow server with isolated router and stable directory dependencies.

test/Capacitor.Cli.Tests.Unit/Commands/ToolCallBudgetTests.cs

UninstallCommandTests.csTest uninstall with injected project paths +28/-44

Test uninstall with injected project paths

• Stops mutating the process directory, passes per-test WorkingDirectory values, and restores parallel execution where

[Comment truncated to fit github's 65,536-char limit.]

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