Skip to content

fix(workspace): prioritize custom files over installation data and isolate user workspaces - #429

Closed
undead2146 wants to merge 1 commit into
developmentfrom
t3code/user-directory-workspaces
Closed

fix(workspace): prioritize custom files over installation data and isolate user workspaces#429
undead2146 wants to merge 1 commit into
developmentfrom
t3code/user-directory-workspaces

Conversation

@undead2146

Copy link
Copy Markdown
Member

Summary

Resolves #42 by ensuring custom files (mods, patches, game clients, addons, language packs, maps, modding tools) take strict precedence over base game installation data across all workspace strategies (FullCopyStrategy, HardLinkStrategy, HybridCopySymlinkStrategy, SymlinkOnlyStrategy), regardless of manifest enumeration order. Workspaces in user directories remain completely isolated from the original game installation so base files are never modified, and launching requires no administrative privileges.

Root Cause

Workspace strategies previously processed manifest files in arbitrary or collection-dependent order, and in some strategies (HybridCopySymlinkStrategy) looped over manifests in sequence without global conflict deduplication. This allowed base game installation files to overwrite mod or patch files when manifests were structured with the mod first, or caused duplicate progress and disk estimation. Additionally, integration tests on Linux and macOS had false-negative admin skip conditions (!isWindows || !isAdmin) which prevented symlink/hybrid workspace tests from executing on Unix platforms.

Changes

  • Core (WorkspaceConfigurationExtensions): Added GetPrioritizedWorkspaceFiles extension method to deduplicate workspace files with deterministic, priority-ordered selection using ContentTypePriority (Mod > Patch > GameClient > ModdingTool > Addon > LanguagePack > Map > GameInstallation).
  • Workspace Strategies (FullCopyStrategy, HardLinkStrategy, HybridCopySymlinkStrategy, SymlinkOnlyStrategy): Standardized all four strategies to use GetPrioritizedWorkspaceFiles(), processing only winning files once, eliminating redundant disk overwrites, and calculating accurate deduplicated disk usage and progress.
  • Tests (WorkspacePrioritizationVerifyTests, WorkspaceIntegrationTests, GameProfileWorkspaceIntegrationTest, WorkspaceCasIntegrationTests):
    • Corrected test skip conditions from (!isWindows || !isAdmin) to (isWindows && !isAdmin) so Linux and macOS properly run full symlink and hybrid workspace integration tests.
    • Added comprehensive verification tests for full content type priority hierarchy, order independence, strategy materialization, and user directory workspace isolation.

Verification

  • Targeted unit and integration tests passing
  • Verified cross-platform compatibility across Windows, Linux, and macOS
  • Adheres to primary constructor, Result pattern, no this., and zero magic constants rules

Closes #42


Created with Gemini 3.7 Flash via Antigravity

…olate user workspaces

- Add GetPrioritizedWorkspaceFiles extension to deduplicate workspace files with strict ContentTypePriority ordering regardless of manifest order
- Update FullCopyStrategy, HardLinkStrategy, HybridCopySymlinkStrategy, and SymlinkOnlyStrategy to use prioritized workspace files
- Fix false-negative test skip conditions in workspace and CAS integration tests on Linux and macOS
- Expand WorkspacePrioritizationVerifyTests with comprehensive hierarchy, order-independence, and user workspace isolation tests

Closes #42
@qodo-code-review

Copy link
Copy Markdown

ⓘ Your Qodo trial ends soon. Ask your workspace admin to set up billing to keep reviews running after the trial. Manage billing

@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 25 minutes.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ab17b985-186e-414f-a5f4-d86989833d69

📥 Commits

Reviewing files that changed from the base of the PR and between 19678f2 and eef2b46.

📒 Files selected for processing (9)
  • GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs
  • GenHub/GenHub.Tests/GenHub.Tests.Core/Features/Workspace/GameProfileWorkspaceIntegrationTest.cs
  • GenHub/GenHub.Tests/GenHub.Tests.Core/Features/Workspace/WorkspaceIntegrationTests.cs
  • GenHub/GenHub.Tests/GenHub.Tests.Core/Features/Workspace/WorkspacePrioritizationVerifyTests.cs
  • GenHub/GenHub.Tests/GenHub.Tests.Core/WorkspaceCasIntegrationTests.cs
  • GenHub/GenHub/Features/Workspace/Strategies/FullCopyStrategy.cs
  • GenHub/GenHub/Features/Workspace/Strategies/HardLinkStrategy.cs
  • GenHub/GenHub/Features/Workspace/Strategies/HybridCopySymlinkStrategy.cs
  • GenHub/GenHub/Features/Workspace/Strategies/SymlinkOnlyStrategy.cs

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.

@deepsource-io

deepsource-io Bot commented Aug 30, 2026

Copy link
Copy Markdown

DeepSource Code Review

We reviewed changes in 19678f2...eef2b46 on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.

See full review on DeepSource ↗

PR Report Card

Overall Grade   Security  

Reliability  

Complexity  

Hygiene  

Code Review Summary

Analyzer Status Updated (UTC) Details
C# Aug 30, 2026 6:50p.m. Review ↗
JavaScript Aug 30, 2026 6:50p.m. Review ↗
Shell Aug 30, 2026 6:50p.m. Review ↗
Secrets Aug 30, 2026 6:50p.m. Review ↗

Important

AI Review is run only on demand for your team. We're only showing results of static analysis review right now. To trigger AI Review, comment @deepsourcebot review on this thread.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Prioritize custom content across isolated workspace strategies

🐞 Bug fix 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Resolve duplicate workspace paths using deterministic content-type priority across every strategy.
• Materialize custom files in isolated user workspaces without modifying base installations.
• Correct Unix symlink test coverage and verify priority, strategy, and isolation behavior.
Diagram

graph TD
  M["Content manifests"] --> P["Priority resolver"] --> W["Winning files"]
  W --> F["Full copy"] --> U["User workspace"]
  W --> H["Hard links"] --> U
  W --> Y["Hybrid links"] --> U
  W --> S["Symlink only"] --> U
Loading
High-Level Assessment

The centralized priority resolver is the strongest approach because every strategy receives the same deduplicated file-and-manifest pairs, preserving source context while preventing strategy-specific conflict behavior. Per-strategy sorting or relying on manifest ordering would duplicate logic and remain easier to regress.

Files changed (9) +473 / -224

Bug fix (5) +196 / -197
WorkspaceConfigurationExtensions.csCentralize priority-aware workspace file resolution +48/-5

Centralize priority-aware workspace file resolution

• Adds null-safe, case-insensitive deduplication that selects files by content-type priority with deterministic same-priority tie-breaking. Introduces a file-and-manifest result used by strategies that require source context.

GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs

FullCopyStrategy.csCopy only priority-winning workspace files +46/-68

Copy only priority-winning workspace files

• Uses centralized prioritized file pairs instead of processing every conflicting version. Disk estimates, progress, byte accounting, source resolution, and CAS handling now operate on the deduplicated winners.

GenHub/GenHub/Features/Workspace/Strategies/FullCopyStrategy.cs

HardLinkStrategy.csReuse centralized hard-link conflict resolution +3/-16

Reuse centralized hard-link conflict resolution

• Replaces local priority grouping with the shared resolver and directly processes each winning file with its owning manifest.

GenHub/GenHub/Features/Workspace/Strategies/HardLinkStrategy.cs

HybridCopySymlinkStrategy.csDeduplicate hybrid copy and link materialization +90/-96

Deduplicate hybrid copy and link materialization

• Processes each priority-winning path once while retaining its manifest for local and CAS source resolution. Estimates, classification, progress, and copied-versus-linked accounting now reflect deduplicated workspace files.

GenHub/GenHub/Features/Workspace/Strategies/HybridCopySymlinkStrategy.cs

SymlinkOnlyStrategy.csSymlink only prioritized workspace targets +9/-12

Symlink only prioritized workspace targets

• Filters and deduplicates workspace-targeted files before parallel link creation. Disk estimates and progress counts now match the actual winning file set.

GenHub/GenHub/Features/Workspace/Strategies/SymlinkOnlyStrategy.cs

Tests (4) +277 / -27
GameProfileWorkspaceIntegrationTest.csRun symlink workspace scenarios on Unix +4/-4

Run symlink workspace scenarios on Unix

• Changes administrator checks so symlink and hybrid scenarios skip only on non-admin Windows hosts. Linux and macOS now execute the relevant integration paths.

GenHub/GenHub.Tests/GenHub.Tests.Core/Features/Workspace/GameProfileWorkspaceIntegrationTest.cs

WorkspaceIntegrationTests.csCorrect cross-platform strategy skip condition +1/-1

Correct cross-platform strategy skip condition

• Allows symlink-based end-to-end workspace tests to run on Unix while retaining the Windows administrator requirement.

GenHub/GenHub.Tests/GenHub.Tests.Core/Features/Workspace/WorkspaceIntegrationTests.cs

WorkspacePrioritizationVerifyTests.csVerify priority ordering and workspace isolation +269/-19

Verify priority ordering and workspace isolation

• Expands coverage for order-independent conflict resolution, workspace-target filtering, and winning-manifest selection. Adds full-copy and hybrid materialization tests confirming custom content wins while base files remain unchanged.

GenHub/GenHub.Tests/GenHub.Tests.Core/Features/Workspace/WorkspacePrioritizationVerifyTests.cs

WorkspaceCasIntegrationTests.csEnable CAS link integration testing on Unix +3/-3

Enable CAS link integration testing on Unix

• Restricts the privilege-based skip to non-admin Windows environments so Unix CAS linking behavior is exercised.

GenHub/GenHub.Tests/GenHub.Tests.Core/WorkspaceCasIntegrationTests.cs

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
3.2% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (4) 📜 Skill insights (0)

Grey Divider


Action required

1. Missing winner drops fallback 🐞 Bug ≡ Correctness
Description
GetPrioritizedWorkspaceFiles discards lower-priority candidates before source availability is
checked, so a missing local mod/patch winner prevents FullCopy and Hybrid from materializing an
available base file at the same path. Both strategies treat the missing winner as non-fatal and can
mark the workspace prepared, while validation uses the reduced successful-file count and therefore
does not detect the omitted required destination.
Code

GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[R79-83]

+            .GroupBy(x => x.File.RelativePath, StringComparer.OrdinalIgnoreCase)
+            .Select(g => g
+                .OrderByDescending(x => ContentTypePriority.GetPriority(x.Manifest.ContentType))
+                .ThenByDescending(x => x.ManifestIndex)
+                .First())
Relevance

●●● Strong

This is a concrete regression in the PR’s stated prioritization behavior; recent workspace reviews
accept correctness fixes.

PR-#383
PR-#348

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The selector reduces each conflicting path to a single priority winner before either strategy
resolves or validates its source, unlike the prior nested processing that handled lower-priority
candidates independently. When that winner is a missing local file, both strategies skip it without
recording an error, count only successfully processed files, validate physical files against that
reduced count rather than the prioritized manifest destinations, and then set IsPrepared to true,
allowing an available base candidate to be discarded and the workspace to remain incomplete.

GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[75-85]
GenHub/GenHub/Features/Workspace/Strategies/WorkspaceStrategyBase.cs[325-334]
GenHub/GenHub/Features/Workspace/Strategies/FullCopyStrategy.cs[147-168]
GenHub/GenHub/Features/Workspace/Strategies/HybridCopySymlinkStrategy.cs[157-162]
GenHub/GenHub/Features/Workspace/Strategies/WorkspaceStrategyBase.cs[239-253]
GenHub/GenHub/Features/Workspace/WorkspaceValidator.cs[259-269]
GenHub/GenHub/Features/Workspace/Strategies/FullCopyStrategy.cs[146-152]
GenHub/GenHub/Features/Workspace/Strategies/FullCopyStrategy.cs[185-186]
GenHub/GenHub/Features/Workspace/Strategies/HybridCopySymlinkStrategy.cs[224-225]
GenHub/GenHub.Tests/GenHub.Tests.Core/Features/Workspace/ProcessLocalFileAsyncTests.cs[168-199]

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

## Issue description
Priority deduplication removes lower-priority candidates before the selected source is validated. If a local mod/patch winner is unavailable, FullCopy and Hybrid can silently omit the destination and report successful preparation even when a valid lower-priority base candidate exists.

## Issue Context
Preserve strict priority when the preferred override is available, but resolve candidates with manifest context and select the highest-priority candidate whose source can be materialized, or explicitly fail preparation when no acceptable source is available. `ValidateSourceFile` currently returns `false` rather than failing for missing local files, after which the strategies can mark the workspace prepared; validation must not rely only on the reduced count of successfully processed files or leave a manifest destination unaccounted for.

## Fix Focus Areas
- GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[75-85]
- GenHub/GenHub/Features/Workspace/Strategies/FullCopyStrategy.cs[139-186]
- GenHub/GenHub/Features/Workspace/Strategies/HybridCopySymlinkStrategy.cs[155-225]

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



Remediation recommended

2. GetAllUniqueFiles exposes deferred sequence 📘 Rule violation ⚙ Maintainability
Description
The modified public collection API still returns IEnumerable<ManifestFile> backed by a deferred
LINQ query. This permits repeated execution and violates the requirement to expose a read-only
collection that is eagerly materialized.
Code

GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[R30-33]

+            .SelectMany((m, index) => (m.Files ?? []).Select(f => new { File = f, Manifest = m, ManifestIndex = index }))
            .GroupBy(x => x.File.RelativePath, StringComparer.OrdinalIgnoreCase)
            .Select(g => g.OrderByDescending(x => ContentTypePriority.GetPriority(x.Manifest.ContentType))
+                          .ThenByDescending(x => x.ManifestIndex)
Relevance

●●● Strong

Recent reviews accept API safety and eager-materialization fixes; this directly matches the active
collection rule.

PR-#426
PR-#424

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rule 3001326 requires modified public finite collection APIs to avoid raw IEnumerable<T> and
eagerly materialize deferred LINQ queries. The changed query is returned directly without
ToList(), while the public method remains IEnumerable<ManifestFile>.

Rule 3001326: Use IReadOnlyList<T>/IReadOnlyCollection<T> for public collection APIs and eagerly materialize deferred queries
GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[18-35]

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

## Issue description
`GetAllUniqueFiles` exposes a deferred `IEnumerable<ManifestFile>` rather than an eagerly materialized read-only collection.

## Issue Context
The method returns a finite deduplicated collection, so callers should receive a stable `IReadOnlyList<ManifestFile>` or `IReadOnlyCollection<ManifestFile>` without re-running its LINQ pipeline.

## Fix Focus Areas
- GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[18-35]

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


3. GetWorkspaceUniqueFiles remains deferred 📘 Rule violation ⚙ Maintainability
Description
The modified public workspace-file lookup returns a deferred LINQ pipeline through
IEnumerable<ManifestFile>. Its finite result should be materialized and exposed as a read-only
collection.
Code

GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[R53-56]

+            .SelectMany((m, index) => (m.Files ?? []).Select(f => new { File = f, Manifest = m, ManifestIndex = index }))
+            .Where(x => x.File.InstallTarget == ContentInstallTarget.Workspace)
            .GroupBy(x => x.File.RelativePath, StringComparer.OrdinalIgnoreCase)
            .Select(g => g.OrderByDescending(x => ContentTypePriority.GetPriority(x.Manifest.ContentType))
Relevance

●●● Strong

The same public deferred-collection issue applies, and recent repository reviews consistently accept
concrete API and validation fixes.

PR-#426
PR-#424

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rule 3001326 disallows raw deferred IEnumerable<T> from modified public finite collection APIs.
The changed LINQ query is returned without materialization.

Rule 3001326: Use IReadOnlyList<T>/IReadOnlyCollection<T> for public collection APIs and eagerly materialize deferred queries
GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[37-59]

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

## Issue description
`GetWorkspaceUniqueFiles` returns a deferred `IEnumerable<ManifestFile>` instead of an eagerly materialized read-only collection.

## Issue Context
The lookup computes a finite, deduplicated set whose query should execute inside the extension method and produce a stable collection for callers.

## Fix Focus Areas
- GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[37-59]

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


4. FullCopyStrategy.PrepareAsync exceeds complexity 📘 Rule violation ⚙ Maintainability
Description
The modified method has an estimated Sonar-style cognitive complexity of about 18, exceeding the
required maximum of 14. Its nested parallel callback, source selection, validation, hash
verification, progress handling, and exception paths should be decomposed.
Code

GenHub/GenHub/Features/Workspace/Strategies/FullCopyStrategy.cs[R139-142]

+                        if (file.SourceType == ContentSourceType.ContentAddressable && !string.IsNullOrEmpty(file.Hash))
+                        {
+                            // Use CAS content
+                            await CreateCasLinkAsync(file.Hash, destinationPath, manifest.ContentType, ct);
Relevance

●●● Strong

The modified method violates an explicit complexity rule; recent reviews accept maintainability
refactors in changed code.

PR-#427
PR-#383

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rule 3001355 requires every modified method to have cognitive complexity below 15. The modified
PrepareAsync contains nested decisions in its parallel callback at lines 139-170 in addition to
setup branches and multiple exception paths, yielding an estimated Sonar-style score around 18.

Rule 3001355: Limit method cognitive complexity to below 15
GenHub/GenHub/Features/Workspace/Strategies/FullCopyStrategy.cs[69-209]

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

## Issue description
`FullCopyStrategy.PrepareAsync` exceeds the cognitive-complexity limit of 14.

## Issue Context
The parallel callback combines source selection, CAS handling, path resolution, validation, copying, hash verification, progress reporting, and exception translation. Extract cohesive operations while preserving cancellation and priority behavior.

## Fix Focus Areas
- GenHub/GenHub/Features/Workspace/Strategies/FullCopyStrategy.cs[93-183]

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


View medium (2)
5. HybridCopySymlinkStrategy.PrepareAsync exceeds complexity 📘 Rule violation ⚙ Maintainability
Description
The modified method has an estimated Sonar-style cognitive complexity of roughly 27–30, well above
the maximum of 14. CAS handling, essential-file decisions, hash checks, and symlink/hardlink/copy
fallbacks are deeply nested in one method.
Code

GenHub/GenHub/Features/Workspace/Strategies/HybridCopySymlinkStrategy.cs[R120-123]

+                    if (file.SourceType == ContentSourceType.ContentAddressable && !string.IsNullOrEmpty(file.Hash))
                    {
-                        if (file.SourceType == ContentSourceType.ContentAddressable && !string.IsNullOrEmpty(file.Hash))
+                        if (isEssential)
+                        {
Relevance

●●● Strong

The substantially increased nested complexity violates the explicit rule and recent reviews accept
readability and maintainability changes.

PR-#427
PR-#383

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Rule 3001355 requires cognitive complexity below 15. The modified method's nested CAS tree,
essential-file checks, hash verification, symlink-to-hardlink-to-copy fallback, and nested exception
handling produce an estimated Sonar-style complexity around 27–30.

Rule 3001355: Limit method cognitive complexity to below 15
GenHub/GenHub/Features/Workspace/Strategies/HybridCopySymlinkStrategy.cs[67-245]

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

## Issue description
`HybridCopySymlinkStrategy.PrepareAsync` substantially exceeds the cognitive-complexity limit.

## Issue Context
The method combines CAS and filesystem paths, essential and non-essential behavior, integrity verification, multiple fallback mechanisms, progress accounting, and exception translation. Split these branches into focused private helpers while forwarding the same cancellation token.

## Fix Focus Areas
- GenHub/GenHub/Features/Workspace/Strategies/HybridCopySymlinkStrategy.cs[118-217]

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


6. Unix case-distinct files collapse 🐞 Bug ≡ Correctness
Description
The new selector always groups paths with OrdinalIgnoreCase, so Hybrid now treats distinct Unix
destinations such as Data/foo and Data/Foo as one conflict and materializes only one file. The
repository's path policy explicitly uses case-sensitive comparison outside Windows, making this a
cross-platform data omission.
Code

GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[79]

+            .GroupBy(x => x.File.RelativePath, StringComparer.OrdinalIgnoreCase)
Relevance

●●● Strong

The finding conflicts with repository path semantics and the PR claims cross-platform compatibility;
recent workspace fixes are accepted.

PR-#383
PR-#348

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The prioritized list collapses case-only differences and Hybrid iterates only that list.
PathHelper.PathComparer documents and implements case-sensitive path collection semantics on
non-Windows platforms.

GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[75-85]
GenHub/GenHub/Features/Workspace/Strategies/HybridCopySymlinkStrategy.cs[111-116]
GenHub/GenHub.Core/Helpers/PathHelper.cs[26-41]

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

## Issue description
Workspace conflict grouping unconditionally folds path case, which drops valid case-distinct files on case-sensitive filesystems.

## Issue Context
Use the repository's platform-aware filesystem comparer consistently in all workspace-file grouping helpers, and add a Unix regression test with two case-distinct relative paths.

## Fix Focus Areas
- GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[31-32]
- GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[55-56]
- GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[79-83]
- GenHub/GenHub.Core/Helpers/PathHelper.cs[34-41]

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


Grey Divider

Context sources
✅ Compliance rules (platform): 29 rules
Review mode: 🧠 Deep: This is a substantial cross-cutting workspace behavior change across four strategies, prioritization, CAS/link fallback, isolation, and many independent test and platform paths, creating a dense set of easy-to-miss defects.

Grey Divider

Tip of the day
💡 Did you know, you can enable the Remediation agent and Qodo fixes findings in a dedicated fix PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment on lines +30 to +33
.SelectMany((m, index) => (m.Files ?? []).Select(f => new { File = f, Manifest = m, ManifestIndex = index }))
.GroupBy(x => x.File.RelativePath, StringComparer.OrdinalIgnoreCase)
.Select(g => g.OrderByDescending(x => ContentTypePriority.GetPriority(x.Manifest.ContentType))
.ThenByDescending(x => x.ManifestIndex)

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

1. getalluniquefiles exposes deferred sequence 📘 Rule violation ⚙ Maintainability

The modified public collection API still returns IEnumerable<ManifestFile> backed by a deferred
LINQ query. This permits repeated execution and violates the requirement to expose a read-only
collection that is eagerly materialized.
Agent Prompt
## Issue description
`GetAllUniqueFiles` exposes a deferred `IEnumerable<ManifestFile>` rather than an eagerly materialized read-only collection.

## Issue Context
The method returns a finite deduplicated collection, so callers should receive a stable `IReadOnlyList<ManifestFile>` or `IReadOnlyCollection<ManifestFile>` without re-running its LINQ pipeline.

## Fix Focus Areas
- GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[18-35]

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

Comment on lines +53 to 56
.SelectMany((m, index) => (m.Files ?? []).Select(f => new { File = f, Manifest = m, ManifestIndex = index }))
.Where(x => x.File.InstallTarget == ContentInstallTarget.Workspace)
.GroupBy(x => x.File.RelativePath, StringComparer.OrdinalIgnoreCase)
.Select(g => g.OrderByDescending(x => ContentTypePriority.GetPriority(x.Manifest.ContentType))

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. getworkspaceuniquefiles remains deferred 📘 Rule violation ⚙ Maintainability

The modified public workspace-file lookup returns a deferred LINQ pipeline through
IEnumerable<ManifestFile>. Its finite result should be materialized and exposed as a read-only
collection.
Agent Prompt
## Issue description
`GetWorkspaceUniqueFiles` returns a deferred `IEnumerable<ManifestFile>` instead of an eagerly materialized read-only collection.

## Issue Context
The lookup computes a finite, deduplicated set whose query should execute inside the extension method and produce a stable collection for callers.

## Fix Focus Areas
- GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[37-59]

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

Comment on lines +139 to +142
if (file.SourceType == ContentSourceType.ContentAddressable && !string.IsNullOrEmpty(file.Hash))
{
// Use CAS content
await CreateCasLinkAsync(file.Hash, destinationPath, manifest.ContentType, ct);

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

3. fullcopystrategy.prepareasync exceeds complexity 📘 Rule violation ⚙ Maintainability

The modified method has an estimated Sonar-style cognitive complexity of about 18, exceeding the
required maximum of 14. Its nested parallel callback, source selection, validation, hash
verification, progress handling, and exception paths should be decomposed.
Agent Prompt
## Issue description
`FullCopyStrategy.PrepareAsync` exceeds the cognitive-complexity limit of 14.

## Issue Context
The parallel callback combines source selection, CAS handling, path resolution, validation, copying, hash verification, progress reporting, and exception translation. Extract cohesive operations while preserving cancellation and priority behavior.

## Fix Focus Areas
- GenHub/GenHub/Features/Workspace/Strategies/FullCopyStrategy.cs[93-183]

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

Comment on lines +120 to +123
if (file.SourceType == ContentSourceType.ContentAddressable && !string.IsNullOrEmpty(file.Hash))
{
if (file.SourceType == ContentSourceType.ContentAddressable && !string.IsNullOrEmpty(file.Hash))
if (isEssential)
{

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

4. hybridcopysymlinkstrategy.prepareasync exceeds complexity 📘 Rule violation ⚙ Maintainability

The modified method has an estimated Sonar-style cognitive complexity of roughly 27–30, well above
the maximum of 14. CAS handling, essential-file decisions, hash checks, and symlink/hardlink/copy
fallbacks are deeply nested in one method.
Agent Prompt
## Issue description
`HybridCopySymlinkStrategy.PrepareAsync` substantially exceeds the cognitive-complexity limit.

## Issue Context
The method combines CAS and filesystem paths, essential and non-essential behavior, integrity verification, multiple fallback mechanisms, progress accounting, and exception translation. Split these branches into focused private helpers while forwarding the same cancellation token.

## Fix Focus Areas
- GenHub/GenHub/Features/Workspace/Strategies/HybridCopySymlinkStrategy.cs[118-217]

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

Comment on lines +79 to +83
.GroupBy(x => x.File.RelativePath, StringComparer.OrdinalIgnoreCase)
.Select(g => g
.OrderByDescending(x => ContentTypePriority.GetPriority(x.Manifest.ContentType))
.ThenByDescending(x => x.ManifestIndex)
.First())

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

5. Missing winner drops fallback 🐞 Bug ≡ Correctness

GetPrioritizedWorkspaceFiles discards lower-priority candidates before source availability is
checked, so a missing local mod/patch winner prevents FullCopy and Hybrid from materializing an
available base file at the same path. Both strategies treat the missing winner as non-fatal and can
mark the workspace prepared, while validation uses the reduced successful-file count and therefore
does not detect the omitted required destination.
Agent Prompt
## Issue description
Priority deduplication removes lower-priority candidates before the selected source is validated. If a local mod/patch winner is unavailable, FullCopy and Hybrid can silently omit the destination and report successful preparation even when a valid lower-priority base candidate exists.

## Issue Context
Preserve strict priority when the preferred override is available, but resolve candidates with manifest context and select the highest-priority candidate whose source can be materialized, or explicitly fail preparation when no acceptable source is available. `ValidateSourceFile` currently returns `false` rather than failing for missing local files, after which the strategies can mark the workspace prepared; validation must not rely only on the reduced count of successfully processed files or leave a manifest destination unaccounted for.

## Fix Focus Areas
- GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[75-85]
- GenHub/GenHub/Features/Workspace/Strategies/FullCopyStrategy.cs[139-186]
- GenHub/GenHub/Features/Workspace/Strategies/HybridCopySymlinkStrategy.cs[155-225]

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

.SelectMany((manifest, index) => (manifest.Files ?? Enumerable.Empty<ManifestFile>())
.Where(f => f.InstallTarget == ContentInstallTarget.Workspace)
.Select(file => new { File = file, Manifest = manifest, ManifestIndex = index }))
.GroupBy(x => x.File.RelativePath, StringComparer.OrdinalIgnoreCase)

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

6. Unix case-distinct files collapse 🐞 Bug ≡ Correctness

The new selector always groups paths with OrdinalIgnoreCase, so Hybrid now treats distinct Unix
destinations such as Data/foo and Data/Foo as one conflict and materializes only one file. The
repository's path policy explicitly uses case-sensitive comparison outside Windows, making this a
cross-platform data omission.
Agent Prompt
## Issue description
Workspace conflict grouping unconditionally folds path case, which drops valid case-distinct files on case-sensitive filesystems.

## Issue Context
Use the repository's platform-aware filesystem comparer consistently in all workspace-file grouping helpers, and add a Unix regression test with two case-distinct relative paths.

## Fix Focus Areas
- GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[31-32]
- GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[55-56]
- GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs[79-83]
- GenHub/GenHub.Core/Helpers/PathHelper.cs[34-41]

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

return configuration.Manifests
.SelectMany(m => (m.Files ?? []).Select(f => new { File = f, Manifest = m }))
.SelectMany((m, index) => (m.Files ?? []).Select(f => new { File = f, Manifest = m, ManifestIndex = index }))
.GroupBy(x => x.File.RelativePath, StringComparer.OrdinalIgnoreCase)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

test

.Where(x => x.File.InstallTarget == GenHub.Core.Models.Enums.ContentInstallTarget.Workspace)
.SelectMany((m, index) => (m.Files ?? []).Select(f => new { File = f, Manifest = m, ManifestIndex = index }))
.Where(x => x.File.InstallTarget == ContentInstallTarget.Workspace)
.GroupBy(x => x.File.RelativePath, StringComparer.OrdinalIgnoreCase)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

test

.Select(file => new { File = file, Manifest = manifest, ManifestIndex = index }))
.GroupBy(x => x.File.RelativePath, StringComparer.OrdinalIgnoreCase)
.Select(g => g
.OrderByDescending(x => ContentTypePriority.GetPriority(x.Manifest.ContentType))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

test

.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator);

if (!isWindows || !isAdmin)
if (isWindows && !isAdmin)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

test

if ((strategy == WorkspaceStrategy.SymlinkOnly ||
strategy == WorkspaceStrategy.HybridCopySymlink) &&
(!isWindows || !isAdmin))
isWindows && !isAdmin)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: Same observation as WorkspaceCasIntegrationTests: the silent return makes the test look like it passed on skipped platforms. Recommend [SkippableFact(Skip = ...)] so test reporters reflect that the scenario was not exercised.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator);

if (!isWindows || !isAdmin)
if (isWindows && !isAdmin)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: if (isWindows && !isAdmin) return; silently reports as pass when skipped. Use Skip = "Requires admin on Windows" / [SkippableFact] so skipped scenarios are surfaced in CI rather than masked as green.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator);

if (!isWindows || !isAdmin)
if (isWindows && !isAdmin)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: Same runtime skip concern — prefer [SkippableFact(Skip = "Requires admin on Windows")] to make the skipped run visible in test output.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

// Skip symlink strategies when not admin on Windows
if ((strategy == WorkspaceStrategy.SymlinkOnly || strategy == WorkspaceStrategy.HybridCopySymlink) &&
(!isWindows || !isAdmin))
isWindows && !isAdmin)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: Same skip-pattern observation as above for the parametrized strategy test.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using GenHub.Core.Extensions;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: using Microsoft.Extensions.Logging; is added but the file uses Microsoft.Extensions.Logging.Abstractions (NullLogger) instead — the unqualified Microsoft.Extensions.Logging import is dead and should be removed to keep the alphabetical using list clean.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

using System.Threading.Tasks;
using GenHub.Core.Extensions;
using GenHub.Core.Interfaces.Common;
using GenHub.Core.Interfaces.Storage;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: using GenHub.Core.Interfaces.Storage; is added but appears unused in this file (no ICas* symbols referenced).


Reply with @kilocode-bot fix it to have Kilo Code address this issue.


long totalSize = 0;
foreach (var manifest in configuration.Manifests)
foreach (var file in configuration.GetWorkspaceUniqueFiles())

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: EstimateDiskUsage now uses GetWorkspaceUniqueFiles(), which performs case-insensitive grouping. The returned Count therefore may over- or under-count on case-sensitive file systems, leading to misleading disk-usage estimates on Linux/macOS.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.


long totalUsage = 0;
foreach (var manifest in configuration.Manifests)
foreach (var file in configuration.GetWorkspaceUniqueFiles())

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: Same GetWorkspaceUniqueFiles() case-insensitive issue in HybridCopySymlinkStrategy.EstimateDiskUsage — on Linux/macOS the deduplicated file count may differ from the actual file set, producing skewed disk estimates.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.


// Symbolic links use minimal space - approximate 1KB per link for metadata
return configuration.Manifests.SelectMany(m => m.Files).Count() * LinkOverheadBytes;
return configuration.GetWorkspaceUniqueFiles().Count() * LinkOverheadBytes;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: Same case-insensitive GetWorkspaceUniqueFiles().Count() issue in SymlinkOnlyStrategy.EstimateDiskUsage — on Linux/macOS the link estimate may be incorrect when manifests contain paths that only differ by letter case.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

/// Verifies that GetPrioritizedWorkspaceFiles returns the winning file and manifest pair for all content types.
/// </summary>
[Fact]
public void GetPrioritizedWorkspaceFiles_FullHierarchy_ResolvesCorrectWinningManifests()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: The hierarchy test only exercises four content types but the priority docstring lists eight (Mod, Patch, GameClient, ModdingTool, Addon, LanguagePack, Map, GameInstallation). Consider adding ModdingTool/Addon/LanguagePack/Map manifests to make this test actually cover the full hierarchy it claims to test.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

return configuration.Manifests
.SelectMany(m => (m.Files ?? []).Select(f => new { File = f, Manifest = m }))
.SelectMany((m, index) => (m.Files ?? []).Select(f => new { File = f, Manifest = m, ManifestIndex = index }))
.GroupBy(x => x.File.RelativePath, StringComparer.OrdinalIgnoreCase)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: Test-only comment - needs real review text.

return configuration.Manifests
.SelectMany(m => (m.Files ?? []).Select(f => new { File = f, Manifest = m }))
.SelectMany((m, index) => (m.Files ?? []).Select(f => new { File = f, Manifest = m, ManifestIndex = index }))
.GroupBy(x => x.File.RelativePath, StringComparer.OrdinalIgnoreCase)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: GroupBy(..., StringComparer.OrdinalIgnoreCase) deduplicates by case-insensitive path. On Linux/macOS, file systems are case-sensitive, so distinct files such as Config.ini and config.ini would be wrongly merged and one would be dropped from every workspace strategy that consumes this list. The grouping should follow the case sensitivity of the host file system (e.g. StringComparer.Ordinal on Unix, OrdinalIgnoreCase on Windows).


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

.Where(x => x.File.InstallTarget == GenHub.Core.Models.Enums.ContentInstallTarget.Workspace)
.SelectMany((m, index) => (m.Files ?? []).Select(f => new { File = f, Manifest = m, ManifestIndex = index }))
.Where(x => x.File.InstallTarget == ContentInstallTarget.Workspace)
.GroupBy(x => x.File.RelativePath, StringComparer.OrdinalIgnoreCase)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: Same case-insensitive grouping concern as above in GetWorkspaceUniqueFiles. On Linux/macOS this drops legitimately distinct paths that only differ in letter case. The same fix (host-aware comparer) should be applied here.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

.Select(file => new { File = file, Manifest = manifest, ManifestIndex = index }))
.GroupBy(x => x.File.RelativePath, StringComparer.OrdinalIgnoreCase)
.Select(g => g
.OrderByDescending(x => ContentTypePriority.GetPriority(x.Manifest.ContentType))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: When two manifests share the same ContentType priority, the tie-breaker is ThenByDescending(x => x.ManifestIndex) which silently picks the LAST manifest. This is deterministic only when the manifests collection order is stable, but it is also undocumented: a higher-priority Mod placed after a lower-priority Mod would still be lost. Either document the rule or pick by an explicit source priority (manifest id/version) so callers can reason about the outcome.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

.IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator);

if (!isWindows || !isAdmin)
if (isWindows && !isAdmin)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

SUGGESTION: Using a runtime if (isWindows && !isAdmin) return; silently swallows the test on Windows non-admin without informing xUnit. Prefer Skip = ... on the [Fact] attribute (or [SkippableFact]) so the skipped status is visible in test reports rather than reported as a passing green test.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

return configuration.Manifests
.SelectMany(m => (m.Files ?? []).Select(f => new { File = f, Manifest = m }))
.SelectMany((m, index) => (m.Files ?? []).Select(f => new { File = f, Manifest = m, ManifestIndex = index }))
.GroupBy(x => x.File.RelativePath, StringComparer.OrdinalIgnoreCase)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: (Replaces earlier placeholder.) GroupBy(..., StringComparer.OrdinalIgnoreCase) deduplicates by case-insensitive path. On Linux/macOS, file systems are case-sensitive, so distinct files such as Config.ini and config.ini would be wrongly merged and one would be dropped from every workspace strategy that consumes this list. The grouping should follow the case sensitivity of the host file system (e.g. StringComparer.Ordinal on Unix, OrdinalIgnoreCase on Windows).


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

@kilo-code-bot

kilo-code-bot Bot commented Aug 30, 2026

Copy link
Copy Markdown

Code Review Summary

Status: 14 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 5
SUGGESTION 9
Issue Details (click to expand)

WARNING

File Line Issue
GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs 31 GroupBy(..., StringComparer.OrdinalIgnoreCase) merges distinct paths on case-sensitive file systems (Linux/macOS); use host-aware comparer
GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs 55 Same case-insensitive grouping concern in GetWorkspaceUniqueFiles
GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs 81 Tie-breaker ThenByDescending(ManifestIndex) silently picks last manifest; undocumented and order-dependent
GenHub/GenHub/Features/Workspace/Strategies/FullCopyStrategy.cs 56 EstimateDiskUsage uses case-insensitive GetWorkspaceUniqueFiles(), producing wrong estimates on Unix
GenHub/GenHub/Features/Workspace/Strategies/HybridCopySymlinkStrategy.cs 51 Same case-insensitive counting issue in HybridCopySymlinkStrategy.EstimateDiskUsage
GenHub/GenHub/Features/Workspace/Strategies/SymlinkOnlyStrategy.cs 51 Same case-insensitive counting issue in SymlinkOnlyStrategy.EstimateDiskUsage

SUGGESTION

File Line Issue
GenHub/GenHub.Tests/GenHub.Tests.Core/WorkspaceCasIntegrationTests.cs 161 Silent runtime skip — prefer [SkippableFact] so CI reports the skipped status
GenHub/GenHub.Tests/GenHub.Tests.Core/Features/Workspace/WorkspaceIntegrationTests.cs 117 Silent runtime skip — prefer [SkippableFact]
GenHub/GenHub.Tests/GenHub.Tests.Core/Features/Workspace/GameProfileWorkspaceIntegrationTest.cs 173 Silent runtime skip — prefer [SkippableFact]
GenHub/GenHub.Tests/GenHub.Tests.Core/Features/Workspace/GameProfileWorkspaceIntegrationTest.cs 231 Silent runtime skip — prefer [SkippableFact]
GenHub/GenHub.Tests/GenHub.Tests.Core/Features/Workspace/GameProfileWorkspaceIntegrationTest.cs 339 Silent runtime skip — prefer [SkippableFact]
GenHub/GenHub.Tests/GenHub.Tests.Core/Features/Workspace/WorkspacePrioritizationVerifyTests.cs 7 Unused using Microsoft.Extensions.Logging;
GenHub/GenHub.Tests/GenHub.Tests.Core/Features/Workspace/WorkspacePrioritizationVerifyTests.cs 9 Unused using GenHub.Core.Interfaces.Storage;
GenHub/GenHub.Tests/GenHub.Tests.Core/Features/Workspace/WorkspacePrioritizationVerifyTests.cs 116 Hierarchy test only covers 4 of 8 content types; expand to cover all
Files Reviewed (9 files)
  • GenHub/GenHub.Core/Extensions/WorkspaceConfigurationExtensions.cs - 3 issues
  • GenHub/GenHub.Tests/GenHub.Tests.Core/Features/Workspace/GameProfileWorkspaceIntegrationTest.cs - 3 issues
  • GenHub/GenHub.Tests/GenHub.Tests.Core/Features/Workspace/WorkspaceIntegrationTests.cs - 1 issue
  • GenHub/GenHub.Tests/GenHub.Tests.Core/Features/Workspace/WorkspacePrioritizationVerifyTests.cs - 3 issues
  • GenHub/GenHub.Tests/GenHub.Tests.Core/WorkspaceCasIntegrationTests.cs - 1 issue
  • GenHub/GenHub/Features/Workspace/Strategies/FullCopyStrategy.cs - 1 issue
  • GenHub/GenHub/Features/Workspace/Strategies/HardLinkStrategy.cs - 0 issues
  • GenHub/GenHub/Features/Workspace/Strategies/HybridCopySymlinkStrategy.cs - 1 issue
  • GenHub/GenHub/Features/Workspace/Strategies/SymlinkOnlyStrategy.cs - 1 issue

Fix these issues in Kilo Cloud


Reviewed by minimax-m3:free · Input: 96.1K · Output: 11.8K · Cached: 2.3M

@undead2146 undead2146 closed this Aug 30, 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.

Create workspaces in a user directory with custom files that take preference on the original game data

1 participant