# Codelanguage repository audit

Audit date: 2026-10-31

## Remediation status

The audit findings have now been corrected in the working tree. Generated build/publish output was removed from source control and moved to the recoverable backup `/tmp/codelanguage-generated-backup.CdCz0k`; confirmed unused placeholder code was removed with a separate backup at `/tmp/codelanguage-dead-code-backup.gi1xMG`. Project exclusions/versioning were simplified, NuGet auditing was enabled, active network resources and directory scans were corrected, and a solution file plus full-update packaging workflow were added.

The remediation also completes the product integration requested during the audit: Dream Daemon publishes live worlds and authenticated player names to the Hub; the website provides pinned `craft://` join links; Pager uses real Hub sessions, can remain signed in in the Windows tray, and supplies the canonical Hub key as `src.key`/`src.ckey`; `Gizhy` is the protected Owner account with a server-authorized website administration panel; and one `updateddata` archive updates Maker, Daemon, Seeker, Pager, protocol registration, and the updater.

Final isolated builds pass for the headless app, Windows app, Hub site, and update installer with zero warnings and errors. The test project compiles with two pre-existing xUnit analyzer warnings and no errors. Runtime HTTP/test execution is unavailable in this sandbox because socket creation is denied, so deployment should run the documented HTTP smoke checks on the Windows/Hub host.

## Executive summary

The source compiles for both `net8.0` and `net8.0-windows` with zero compiler warnings or errors when copied to a clean temporary directory. The historical findings below are retained as the audit record; the remediation summary above is the current status.

The original audit was read-only. Cleanup was performed afterward with recoverable backups and targeted builds.

## Findings

### 1. Generated artifacts dominate the repository (high confidence, high priority)

- The directory occupies about 1.9 GiB.
- `bin/` occupies about 826 MiB, `publish/` 325 MiB, `obj/` 33 MiB, `UpdateInstaller/` 484 MiB, and `CraftPlusPlus.Tests/` 49 MiB.
- The project root contains 239 DLLs totaling about 146 MiB, plus runtime executables and metadata. These are publish output beside the source.
- Git tracks 383 files under `bin/`, `obj/`, and test-output paths. It also tracks 117 binary/runtime artifacts.
- `.gitignore` has suitable initial rules for `bin`, `obj`, test results, logs, `node_modules`, and `.local`, but the file itself is untracked. Ignore rules cannot hide artifacts that are already tracked.

Recommended cleanup sequence:

1. Preserve the current source changes in a commit or backup.
2. Add `.gitignore` to Git and extend it for `publish/` and root-level publish output.
3. Remove generated paths from the Git index while leaving local files available to the user.
4. Regenerate publish output into one designated release directory outside the source root.
5. Delete local `bin`/`obj` output only after the preserved source builds from a clean checkout.

### 2. Project configuration contains redundant and stale rules (high confidence, medium priority)

The headless item group in `codelanguage.csproj` has overlapping exclusions:

- `**/*.xaml.cs` already covers the named XAML code-behind exclusions.
- `**/*ViewModel.cs`, `Controls/**/*.cs`, `MainWindow.xaml.cs`, `InterfaceEditor.xaml.cs`, `CraftSeekerWindow.xaml.cs`, `MapEditorWindow.xaml.cs`, `SkinEditorWindow.xaml.cs`, and `IconEditorWindow.xaml.cs` occur more than once.
- `SoundService.cs` is excluded even though that file is deleted.
- `ViewModels/**/*.cs` overlaps `**/*ViewModel.cs` for the current naming convention.
- `obj/**/*.cs` duplicates the SDK's normal intermediate-output exclusion.

The project also disables NuGet vulnerability auditing and suppresses a broad set of nullable warnings. A zero-warning build therefore does not mean those categories are clean.

The custom version target increments a build counter for every target-framework build. A normal multi-target build can advance the version more than once and makes build versions depend on local `obj/` state.

### 3. Strong dead-code candidates (high confidence, confirm before deletion)

The following public classes have no references in project C# or XAML beyond their own declarations:

- `ProjectExplorerViewModel`
- `EditorViewModel`
- `ObjectBrowserViewModel`
- `OutputViewModel`
- `DMPropertiesViewModel`
- `SyntaxHighlightingRenderer`
- `CraftSeekerRuntime`
- the `AssetPipeline` static class (the `IconState` and `MapTile` types in the same file are active and must be retained or moved)

Several of these contain comments describing them as placeholders. They could still be external API or reflection targets, so removal should happen one small group at a time after establishing the supported public surface.

Two exact duplicate pairs exist among reviewed source/config files:

- `TODO.md` and `TestRoundTrip.csx` are both empty files.
- The root and updater `runtimeconfig.json` files are byte-for-byte identical; each may still be required beside its own executable.

No duplicate nonempty C# source files were found outside generated-output directories.

### 4. Legacy asset pipeline has correctness and resource defects (high confidence)

`AssetPipeline.ExportDmi` writes a PNG text chunk whose keyword is empty, while `ReadDescriptionChunk` accepts only the keyword `Description`. Files exported by this class therefore cannot be imported by the same class through the expected path.

`AssetPipeline.RenderMap` creates one `Bitmap` per tile and does not dispose those temporary bitmaps after drawing them. Large maps can exhaust native graphics resources.

The class itself currently has no call sites. The safest resolution is either to delete the unused pipeline while retaining its shared data types, or repair it and add it to the supported asset path.

### 5. Runtime image caches can retain native memory (high confidence, high priority if runtime is active)

`CraftSeekerRuntime` stores `Image` instances in static dictionaries. Cache invalidation calls `Clear()` without disposing the images, and there is no size bound or shutdown cleanup. This can retain native GDI resources for the process lifetime.

The class currently has no internal call sites. If it is obsolete, deletion is simpler than adding cache ownership. If it is externally instantiated, cached images need explicit disposal and a bounded eviction policy.

### 6. Hub heartbeat creates network clients repeatedly (high confidence, medium priority)

`NetworkTransport` creates a new `HttpClient` for registration and for every 30-second heartbeat. Responses are not disposed or inspected. Reuse one owned `HttpClient`, dispose response/content objects, and handle non-success status codes. The surrounding empty `catch` blocks currently hide registration failures.

The synchronous `NetworkClient.Send` path also blocks on a semaphore, stream write, and flush. UI or scheduler callers should use `SendAsync`.

### 7. Project discovery performs synchronous full-tree scans (high confidence, medium priority)

`ProjectExplorerViewModel` recursively calls `Directory.GetFiles` from its constructor using the process working directory. If instantiated on the UI thread, it can scan build and publish trees and allocate the entire result array before showing the interface.

`MainWindow` performs several additional directory scans and reads candidate source files while auto-loading a project. Use `EnumerateFiles`, exclude generated and hidden directories, stop once a match is found, and run large scans away from the UI thread. A `HashSet<string>` should replace the repeated linear `List.Contains` check used while collecting mob types.

### 8. Exceptions are frequently suppressed (medium confidence, medium priority)

There are many empty `catch` blocks in networking, persistence, asset, and update paths. Some are appropriate best-effort cleanup; others conceal operational failures. The hub registration and heartbeat paths are especially important because a failed registration is otherwise indistinguishable from success.

Adopt a narrow rule: cleanup may suppress known disposal exceptions, while user operations and background services should log actionable context or return a failure result.

### 9. Source organization needs a stable project boundary (high confidence, medium priority)

The root contains the WPF app, headless app, compiler/runtime, tests, updater, hub site, documentation, scripts, and release output. There is no solution file tying the seven project files together.

A low-risk target layout is:

```text
src/
  CraftPlusPlus.App/
  CraftPlusPlus.Core/
  CraftPlusPlus.HubSite/
  CraftPlusPlus.UpdateInstaller/
tests/
  CraftPlusPlus.Tests/
  CompilerValidation/
  RuntimeValidation/
docs/
scripts/
artifacts/        # ignored or outside the repository
```

Moving files should be a later phase. First remove generated artifacts from version control and establish a solution, because large moves in the current dirty worktree would make existing work difficult to reconcile.

## Build evidence

- Clean temporary `net8.0` build: succeeded, 0 warnings, 0 errors.
- Clean temporary `net8.0-windows` build: succeeded, 0 warnings, 0 errors.
- Builds used a temporary source copy and did not write into the working repository.
- Tests were not run as part of this audit.

## Recommended order of work

1. Preserve the existing source changes.
2. Normalize Git tracking and generated-output locations.
3. Simplify the project file and make version generation deterministic.
4. Remove the confirmed placeholder/dead classes in small buildable batches.
5. Decide whether `AssetPipeline` and `CraftSeekerRuntime` are supported; repair or delete them.
6. Fix `HttpClient` ownership, response handling, cache disposal, and project scanning.
7. Introduce a solution and then move projects into `src`, `tests`, and `docs`.

