diff --git a/.claude/knowledge/codebase-graph.md b/.claude/knowledge/codebase-graph.md
new file mode 100644
index 0000000..3fb36e3
--- /dev/null
+++ b/.claude/knowledge/codebase-graph.md
@@ -0,0 +1,35 @@
+# Codebase Dependency Graph
+
+Generated by graphify-dotnet from the `src/` directory. Regenerates automatically before
+each build of `Perpetuum.Server` (requires .NET 10 SDK for the graphify tool — `dotnet tool restore` from the
+solution root).
+
+## Artifacts
+
+- **`docs/graph/graph.json`** — machine-readable graph; gitignored,
+ present after any local `Perpetuum.Server` build
+- **`docs/graph/GRAPH_REPORT.md`** — Markdown architecture report; gitignored, same condition
+- **GitHub Wiki** — latest report published by CI:
+ `https://github.com/OpenPerpetuum/PerpetuumServer2/wiki/Codebase-Graph`
+
+## Graph Structure
+
+Nodes represent C# classes, methods, and namespaces (type: `Entity` or `File`).
+Edges represent inheritance, composition, and namespace imports.
+Communities (Louvain clustering, clusters) group related symbols.
+
+## How to Use
+
+**Impact analysis** — when a type is modified, query `graph.json` for edges pointing to that
+node's `id` to find all dependents before assessing blast radius.
+
+**God-node awareness** — the top 10 most-connected symbols are listed in `GRAPH_REPORT.md`
+under "God Nodes". These are the highest-risk symbols to change: `RelocateItems`,
+`LootItemRepository`, `PackItems`, `ChangeAmmo`, `UnstackAmount`, `EquipModule`,
+`ListContainer`, `IWeatherService`, `SetItemName`, `ILootItemRepository` — see `GRAPH_REPORT.md` for the full list.
+
+**Subsystem navigation** — look up a class node in `graph.json` to find its `community` ID,
+then find other nodes with the same `community` to discover related types in the same cluster.
+
+**Dependency verification** — check for edge paths between two namespaces to confirm whether
+an unintended cross-subsystem dependency would be introduced by a change.
diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
new file mode 100644
index 0000000..ae61a47
--- /dev/null
+++ b/.config/dotnet-tools.json
@@ -0,0 +1,12 @@
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "graphify-dotnet": {
+ "version": "0.7.0",
+ "commands": [
+ "graphify"
+ ]
+ }
+ }
+}
diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index 1e20953..9ba354c 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -57,3 +57,46 @@ jobs:
name: Perpetuum-AdminTool-Installer-${{ github.sha }}
path: ${{ env.Workspace }}/src/Perpetuum.AdminToolInstaller/bin/x64/Release/en-US/*.msi
if: ${{ github.event_name == 'push' }}
+
+ publish-wiki:
+
+ runs-on: windows-latest
+ needs: build
+ if: github.event_name == 'push'
+ permissions:
+ contents: write
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Setup .NET 10 (graphify tool requirement)
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: 10.0.x
+
+ - name: Restore dotnet tools
+ run: dotnet tool restore
+
+ - name: Generate codebase report
+ working-directory: ${{ github.workspace }}
+ run: dotnet tool run graphify run src -o graphify-out -f report
+
+ - name: Publish report to GitHub Wiki
+ shell: pwsh
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ COMMIT_SHA: ${{ github.sha }}
+ run: |
+ git clone "https://x-access-token:$env:GH_TOKEN@github.com/OpenPerpetuum/PerpetuumServer2.wiki.git" wiki-repo
+ Copy-Item "graphify-out/GRAPH_REPORT.md" -Destination "wiki-repo/Codebase-Graph.md" -Force
+ Set-Location wiki-repo
+ git config user.name "github-actions[bot]"
+ git config user.email "github-actions[bot]@users.noreply.github.com"
+ git add "Codebase-Graph.md"
+ $changes = git status --porcelain
+ if ($changes) {
+ git commit -m "Update codebase graph report [$env:COMMIT_SHA]"
+ git push
+ } else {
+ Write-Host "No wiki changes to publish"
+ }
diff --git a/.gitignore b/.gitignore
index 36b1cc1..5238b6c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,3 +23,7 @@ Releases/
.planning/
*.log
*_wpftmp.csproj
+
+# graphify-dotnet generated output (regenerates on build)
+docs/graph/
+graphify-out/
diff --git a/Directory.Build.targets b/Directory.Build.targets
new file mode 100644
index 0000000..374a052
--- /dev/null
+++ b/Directory.Build.targets
@@ -0,0 +1,8 @@
+
+
+
+
+
diff --git a/docs/backlog/improvements.md b/docs/backlog/improvements.md
index 37e6939..9fdb1e1 100644
--- a/docs/backlog/improvements.md
+++ b/docs/backlog/improvements.md
@@ -499,41 +499,32 @@ Installer output should be a single executable or package that operators can dis
---
-## IMPROVEMENT-021 - Upgrade to .NET 10 and Integrate Graphify
+## IMPROVEMENT-021 - Graphify Codebase Graph Integration
-Status: TODO
+Status: DONE
Priority: HIGH
Area: Infrastructure / Tooling / AI
+Spec: docs/superpowers/specs/2026-05-23-improvement-021-graphify-integration-design.md
### Description
-Plan and execute a careful migration of the entire solution from .NET 8 to .NET 10, then integrate the [Graphify](https://github.com/willibrandon/graphify) package (a .NET 10 dependency) to generate a structural graph of the codebase and wire it to Claude for enhanced code understanding and navigation.
-
-### Impact
-.NET 10 (LTS) brings performance improvements, new C# language features, and long-term support beyond .NET 8. The Graphify integration would give Claude (and operators) a machine-readable dependency/call graph of the server codebase, enabling more accurate impact analysis, smarter navigation, and reduced hallucination risk when reasoning about unfamiliar subsystems.
+Integrated `graphify-dotnet` (https://github.com/elbruno/graphify-dotnet) as a local dotnet
+tool. Generates a structural JSON graph and Markdown architecture report before every
+`Perpetuum.Server` build. CI publishes the report to the GitHub Wiki on each push to `develop`.
-### Proposed Implementation
-
-**Phase 1 — .NET 10 upgrade**
-- Audit current NuGet dependencies for .NET 10 compatibility; flag any packages with no .NET 10 target or known breaking changes.
-- Update all `` entries in `.csproj` files from `net8.0` to `net10.0`.
-- Address any breaking API changes surfaced by the build (`dotnet build`): BCL changes, removed APIs, updated semantics.
-- Update the CI workflow (`.github/workflows/dotnet.yml`) to use the .NET 10 SDK.
-- Validate a full Release build and a local server run before proceeding to Phase 2.
-- Update `docs/STACK.md` to reflect the new runtime version.
-
-**Phase 2 — Graphify integration**
-- Add the Graphify NuGet package to the solution (targeting the appropriate project — likely a standalone tooling project or the AdminTool).
-- Configure Graphify to analyze the `PerpetuumServer2` solution and output a dependency/call graph in a Claude-consumable format (JSON, Markdown, or Graphify's native output).
-- Define what graph artifacts are most useful for Claude: namespace dependency graph, class hierarchy, inter-module call graph, or a combination.
-- Automate graph regeneration (e.g. as a pre-build step or CI artifact) so the graph stays current as the codebase evolves.
-- Document how Claude should load and interpret the graph output — update `.claude/knowledge/architecture.md` with a pointer to the graph artifact and a brief explanation of its structure.
+### Implementation
+- `.config/dotnet-tools.json` registers `graphify-dotnet@0.7.0` (command: `graphify`)
+- `Directory.Build.targets` (solution root) fires `GenerateCodeGraph` before `Perpetuum.Server`
+ builds; `ContinueOnError="true"` soft-fails on machines without .NET 10 SDK
+- `-f json,report` produces `docs/graph/graph.json` and `docs/graph/GRAPH_REPORT.md` (gitignored)
+- `.github/workflows/dotnet.yml` `publish-wiki` job pushes `GRAPH_REPORT.md` to GitHub Wiki as
+ `Codebase-Graph.md` on each push to `develop`
+- `.claude/knowledge/codebase-graph.md` added for Claude orientation
### Notes
-.NET 10 is on the STS/LTS release train; verify its LTS status and release date before committing to the upgrade timeline.
-Graphify requires .NET 10 — Phase 1 must be complete and stable before Phase 2 begins.
-The upgrade should be done on a dedicated branch with a full build + manual smoke test before merging.
-Pay special attention to any use of reflection, source generators, or runtime behaviour that changed between .NET 8 and .NET 10.
-Autofac and other DI/serialization libraries should be verified for .NET 10 compatibility early — these are common sources of upgrade friction.
+Phase 2 (.NET 8 → .NET 10 project TFM migration) is deferred as an independent workstream.
+The graphify tool requires .NET 10 SDK but the project TFMs remain at net8.0.
+Run `dotnet tool restore` once after cloning to enable graph regeneration.
+GitHub Wiki must have at least one page initialized before the CI publish job can push.
---
diff --git a/docs/codebase/ARCHITECTURE.md b/docs/codebase/ARCHITECTURE.md
index 04095cf..e2d491c 100644
--- a/docs/codebase/ARCHITECTURE.md
+++ b/docs/codebase/ARCHITECTURE.md
@@ -339,3 +339,15 @@ Post-commit hooks via `Transaction.Current.OnCommited(...)` (`src/Perpetuum/Data
---
*Architecture analysis: 2026-05-11*
+
+## Graph Artifact
+
+A structural graph of this codebase is generated by graphify-dotnet on every `Perpetuum.Server`
+build (requires .NET 10 SDK and `dotnet tool restore`):
+
+- `docs/graph/graph.json` — machine-readable nodes/edges (gitignored, regenerates on build)
+- `docs/graph/GRAPH_REPORT.md` — Markdown architecture report (gitignored, regenerates on build)
+- GitHub Wiki — latest report published by CI on each push to `develop`:
+ `https://github.com/OpenPerpetuum/PerpetuumServer2/wiki/Codebase-Graph`
+
+See `.claude/knowledge/codebase-graph.md` for how Claude uses these artifacts.
diff --git a/docs/superpowers/plans/2026-05-23-graphify-integration.md b/docs/superpowers/plans/2026-05-23-graphify-integration.md
new file mode 100644
index 0000000..bc2874c
--- /dev/null
+++ b/docs/superpowers/plans/2026-05-23-graphify-integration.md
@@ -0,0 +1,339 @@
+# graphify-dotnet Integration Implementation Plan
+
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
+
+**Goal:** Wire `graphify-dotnet` as a local dotnet tool with a pre-build MSBuild target that commits a structural JSON + HTML knowledge graph of the codebase to `docs/graph/`.
+
+**Architecture:** `.config/dotnet-tools.json` registers the tool; `Directory.Build.targets` at solution root fires a `BeforeBuild` MSBuild target conditioned on `Perpetuum.Server` only. The target runs `graphify-dotnet` with `ContinueOnError="true"` (soft-fail). Two output artifacts (`graph.json`, `graph.html`) are committed. A new `.claude/knowledge/codebase-graph.md` tells Claude how to interpret the graph.
+
+**Tech Stack:** .NET 10 SDK (tool runtime only — project TFMs stay at net8.0), graphify-dotnet 0.7.0, MSBuild, PowerShell
+
+**Spec:** `docs/superpowers/specs/2026-05-23-improvement-021-graphify-integration-design.md`
+
+---
+
+## File Map
+
+| Action | Path | Purpose |
+|---|---|---|
+| Create | `.config/dotnet-tools.json` | Registers `graphify-dotnet@0.7.0` as a local tool |
+| Create | `Directory.Build.targets` | MSBuild pre-build target at solution root |
+| Create | `docs/graph/graph.json` | Committed machine-readable structural graph |
+| Create | `docs/graph/graph.html` | Committed interactive HTML visualization |
+| Create | `.claude/knowledge/codebase-graph.md` | Claude orientation file |
+| Modify | `docs/codebase/ARCHITECTURE.md` | Add graph artifact pointer section |
+| Modify | `docs/backlog/improvements.md` | Update IMPROVEMENT-021 to DONE, correct URL |
+
+---
+
+### Task 1: Register graphify-dotnet as a local dotnet tool
+
+**Files:**
+- Create: `.config/dotnet-tools.json`
+
+- [ ] **Step 1: Create the `.config/` directory and `dotnet-tools.json`**
+
+From the solution root (`E:\MyStuff\Projects\PerpetuumServer2`):
+
+```powershell
+New-Item -ItemType Directory -Force ".config"
+```
+
+Create `.config/dotnet-tools.json` with this content:
+
+```json
+{
+ "version": 1,
+ "isRoot": true,
+ "tools": {
+ "graphify-dotnet": {
+ "version": "0.7.0",
+ "commands": [
+ "graphify-dotnet"
+ ]
+ }
+ }
+}
+```
+
+- [ ] **Step 2: Install the tool**
+
+```
+dotnet tool restore
+```
+
+Expected: output contains a line like `Restored graphify-dotnet (version 0.7.0)`.
+
+If it fails with "SDK version not found" or similar, verify .NET 10 is installed:
+```
+dotnet --list-sdks
+```
+There must be a `10.x.x` entry. Install .NET 10 SDK from https://dot.net if absent.
+
+- [ ] **Step 3: Confirm the registered command name**
+
+```
+dotnet tool list
+```
+
+Expected output (approximate):
+```
+Package Id Version Commands
+----------------------------------------------
+graphify-dotnet 0.7.0 graphify-dotnet
+```
+
+Note the value in the `Commands` column exactly. If it reads something other than `graphify-dotnet` (e.g., just `graphify`), record that value — you will substitute it in Task 2.
+
+- [ ] **Step 4: Check available CLI flags**
+
+```
+dotnet tool run graphify-dotnet --help
+```
+
+Look for flags equivalent to:
+- Input source directory (likely `--input` or `-i` or first positional arg)
+- Output directory (likely `--output` or `-o`)
+- Format selection (likely `--format` or `-f`, with values like `json`, `html`)
+
+If the flag names differ from `--input`, `--output`, `--format`, note the correct names for Task 2.
+
+- [ ] **Step 5: Commit**
+
+```
+git add .config/dotnet-tools.json
+git commit -m "chore: register graphify-dotnet 0.7.0 local tool"
+```
+
+---
+
+### Task 2: Create Directory.Build.targets pre-build target
+
+**Files:**
+- Create: `Directory.Build.targets` (solution root — same folder as `PerpetuumServer2.sln`)
+- Create: `docs/graph/.gitkeep`
+
+- [ ] **Step 1: Create `Directory.Build.targets`**
+
+Create this file at the solution root. If the CLI command name or flags from Task 1 differed from the defaults, update the `Command` attribute accordingly.
+
+```xml
+
+
+
+
+
+
+```
+
+> **Substitution note:** Replace `graphify-dotnet` in `dotnet tool run graphify-dotnet` with the Commands column value from Task 1 Step 3 if different. Replace `--input`, `--output`, `--format json,html` with the correct flags from Task 1 Step 4 if different.
+
+- [ ] **Step 2: Create `docs/graph/` directory with a placeholder**
+
+```powershell
+New-Item -ItemType Directory -Force "docs\graph"
+New-Item -ItemType File -Force "docs\graph\.gitkeep"
+```
+
+- [ ] **Step 3: Build Perpetuum.Server and verify the target fires**
+
+```
+dotnet build src/Perpetuum.Server/Perpetuum.Server.csproj -c Release -p:Platform=x64
+```
+
+Scan the build output for `GenerateCodeGraph`. You should see it listed in the target execution sequence. The tool should run and produce output.
+
+- [ ] **Step 4: Verify graph files were created**
+
+```powershell
+Get-ChildItem "docs\graph"
+```
+
+Expected: `graph.json` and `graph.html` are present alongside `.gitkeep`.
+
+If only `.gitkeep` is present, the target ran but the tool produced no output. Diagnose by running the tool directly:
+```
+dotnet tool run graphify-dotnet --input src --output docs\graph --format json,html
+```
+Check for errors and adjust the `--input` path or format flags as needed, then update `Directory.Build.targets` to match.
+
+- [ ] **Step 5: Commit**
+
+```
+git add Directory.Build.targets docs/graph/.gitkeep
+git commit -m "chore: add graphify pre-build target and graph output directory"
+```
+
+---
+
+### Task 3: Verify graph quality and commit artifacts
+
+**Files:**
+- Verify: `docs/graph/graph.json`
+- Verify: `docs/graph/graph.html`
+
+- [ ] **Step 1: Inspect `graph.json` for meaningful content**
+
+Open `docs/graph/graph.json`. It should contain arrays of nodes and edges. Look for known class names from the codebase — for example `Zone`, `Player`, `Robot`, `EntityDefault`. These should appear as node labels or names.
+
+Expected structure (exact shape depends on graphify-dotnet version):
+```json
+{
+ "nodes": [ { "id": "...", "label": "Zone", ... }, ... ],
+ "edges": [ { "source": "...", "target": "...", ... }, ... ]
+}
+```
+
+If the file is empty or contains only `{}`, the tool ran without errors but found no C# source. Check that the `--input` path in `Directory.Build.targets` resolves to the `src/` directory containing `.cs` files.
+
+- [ ] **Step 2: Open `graph.html` in a browser**
+
+Open `docs/graph/graph.html` directly in a browser (no server needed). Confirm:
+- The page loads without JavaScript console errors
+- Nodes are visible and the graph is interactive (pan, zoom, click)
+- Known class names (`Zone`, `Player`, `Robot`) are findable via any search or filter UI
+
+- [ ] **Step 3: Remove `.gitkeep` now that real files exist**
+
+```powershell
+Remove-Item "docs\graph\.gitkeep"
+```
+
+- [ ] **Step 4: Commit the graph artifacts**
+
+```
+git add docs/graph/
+git commit -m "chore: add initial graphify codebase graph artifacts"
+```
+
+---
+
+### Task 4: Create Claude knowledge orientation file
+
+**Files:**
+- Create: `.claude/knowledge/codebase-graph.md`
+
+- [ ] **Step 1: Create the `.claude/knowledge/` directory**
+
+```powershell
+New-Item -ItemType Directory -Force ".claude\knowledge"
+```
+
+- [ ] **Step 2: Create `.claude/knowledge/codebase-graph.md`**
+
+```markdown
+# Codebase Dependency Graph
+
+Generated by graphify-dotnet. Regenerates automatically before each build of Perpetuum.Server
+(requires .NET 10 SDK and `dotnet tool restore` from the solution root).
+
+- Machine-readable graph: `docs/graph/graph.json`
+- Interactive visualization: `docs/graph/graph.html` (open in browser)
+
+## Structure
+
+Nodes represent C# classes, interfaces, and namespaces.
+Edges represent inheritance, composition, and namespace imports.
+Communities (Louvain clustering) group related classes into clusters.
+
+## How to use this
+
+- **Impact analysis:** When a type is modified, query `graph.json` for edges pointing to it
+ to find all dependents before assessing blast radius.
+- **Subsystem navigation:** Look up a class in the graph to find its community cluster
+ and discover related types in the same subsystem.
+- **Dependency verification:** Check the graph to confirm no unintended cross-subsystem
+ dependency is introduced by a change.
+```
+
+- [ ] **Step 3: Commit**
+
+```
+git add .claude/knowledge/codebase-graph.md
+git commit -m "docs: add Claude orientation file for codebase graph"
+```
+
+---
+
+### Task 5: Update ARCHITECTURE.md and backlog
+
+**Files:**
+- Modify: `docs/codebase/ARCHITECTURE.md`
+- Modify: `docs/backlog/improvements.md`
+
+- [ ] **Step 1: Add graph artifact section to ARCHITECTURE.md**
+
+Open `docs/codebase/ARCHITECTURE.md`. After the opening comment (``), insert a new section before the `# Architecture` heading:
+
+```markdown
+## Graph Artifact
+
+A committed structural graph of this codebase is available at `docs/graph/`:
+- `graph.json` — machine-readable nodes/edges for programmatic use
+- `graph.html` — interactive browser visualization
+
+See `.claude/knowledge/codebase-graph.md` for how Claude uses these files.
+Regenerated automatically before each `Perpetuum.Server` build (requires `dotnet tool restore`).
+
+```
+
+- [ ] **Step 2: Update IMPROVEMENT-021 in the backlog**
+
+Open `docs/backlog/improvements.md`. Find the `## IMPROVEMENT-021` section and replace it entirely with:
+
+```markdown
+## IMPROVEMENT-021 - Graphify Codebase Graph Integration
+
+Status: DONE
+Priority: HIGH
+Area: Infrastructure / Tooling / AI
+Spec: docs/superpowers/specs/2026-05-23-improvement-021-graphify-integration-design.md
+
+### Description
+Integrated `graphify-dotnet` (https://github.com/elbruno/graphify-dotnet) as a local dotnet
+tool with an MSBuild pre-build target. Regenerates a structural JSON + HTML knowledge graph
+of the codebase before every `Perpetuum.Server` build. Artifacts committed to `docs/graph/`.
+Claude reads `graph.json` for impact analysis and navigation.
+
+### Implementation
+- `.config/dotnet-tools.json` registers `graphify-dotnet@0.7.0`
+- `Directory.Build.targets` (solution root) fires `GenerateCodeGraph` before `Perpetuum.Server` builds; `ContinueOnError="true"` soft-fails on machines without .NET 10 SDK
+- `docs/graph/graph.json` and `docs/graph/graph.html` committed and kept current
+- `.claude/knowledge/codebase-graph.md` added for Claude orientation
+
+### Notes
+Phase 2 (.NET 8 → .NET 10 project TFM migration) is deferred as an independent workstream.
+The graphify tool requires .NET 10 SDK but does not require project TFMs to change.
+Run `dotnet tool restore` once after cloning to enable graph regeneration.
+
+---
+```
+
+- [ ] **Step 3: Commit**
+
+```
+git add docs/codebase/ARCHITECTURE.md docs/backlog/improvements.md
+git commit -m "docs: update ARCHITECTURE.md and backlog for graphify integration (IMPROVEMENT-021)"
+```
+
+---
+
+## Manual Validation Checklist
+
+After all tasks are complete:
+
+1. Fresh clone (or `dotnet tool restore` on existing clone) → `dotnet tool restore` succeeds
+2. `dotnet build src/Perpetuum.Server/Perpetuum.Server.csproj -c Release -p:Platform=x64` → builds successfully, `GenerateCodeGraph` target appears in output
+3. `docs/graph/graph.json` exists and contains known class names
+4. `docs/graph/graph.html` opens in browser and renders nodes interactively
+5. Remove .NET 10 SDK or skip `dotnet tool restore`, rebuild → build succeeds (soft-fail confirmed)
+6. `git log --oneline -5` shows all 5 commits from this plan
diff --git a/docs/superpowers/specs/2026-05-23-improvement-021-graphify-integration-design.md b/docs/superpowers/specs/2026-05-23-improvement-021-graphify-integration-design.md
new file mode 100644
index 0000000..960cd20
--- /dev/null
+++ b/docs/superpowers/specs/2026-05-23-improvement-021-graphify-integration-design.md
@@ -0,0 +1,184 @@
+# IMPROVEMENT-021: Graphify Integration Design
+
+**Date:** 2026-05-23
+**Status:** Approved
+**Area:** Infrastructure / Tooling / AI
+
+---
+
+## Overview
+
+Integrate `graphify-dotnet` into the PerpetuumServer2 solution to generate a committed structural knowledge graph of the codebase. The graph is consumed by Claude for accurate impact analysis and navigation, and browsable by operators as an interactive HTML visualization.
+
+This is Phase 1 of IMPROVEMENT-021. The .NET 8→10 migration (Phase 2) is deferred and independent — graphify-dotnet runs as a standalone .NET 10 tool and does not require the project TFMs to change.
+
+---
+
+## Tool
+
+| Property | Value |
+|---|---|
+| NuGet package | `graphify-dotnet` |
+| Version | `0.7.0` |
+| Author | Bruno Capuano (ElBruno) |
+| Source | https://github.com/elbruno/graphify-dotnet |
+| Runtime requirement | .NET 10 SDK (standalone tool — project TFM unchanged) |
+| License | MIT |
+| NuGet dependencies | None |
+
+**Analysis approach:** Tree-sitter AST parsing across 18+ languages; optional AI-enhanced semantic layer (not enabled in this integration — AST-only).
+
+---
+
+## Architecture
+
+### New Artifacts
+
+| File | Purpose |
+|---|---|
+| `.config/dotnet-tools.json` | Registers `graphify-dotnet@0.7.0` as a local dotnet tool |
+| `Directory.Build.targets` (solution root) | `BeforeBuild` target that runs the tool before compiling `Perpetuum.Server` |
+| `docs/graph/graph.json` | Committed machine-readable structural graph (Claude consumption) |
+| `docs/graph/graph.html` | Committed interactive vis.js visualization (operator browsing) |
+| `.claude/knowledge/codebase-graph.md` | Orients Claude on how to load and use the graph |
+
+### Modified Artifacts
+
+| File | Change |
+|---|---|
+| `docs/codebase/ARCHITECTURE.md` | Add a pointer section referencing `docs/graph/` |
+| `docs/backlog/improvements.md` (IMPROVEMENT-021) | Correct GitHub URL, reorder phases, mark Phase 1 in progress |
+
+---
+
+## Pre-Build Target
+
+`Directory.Build.targets` at solution root:
+
+```xml
+
+
+
+
+
+```
+
+**Key properties:**
+- Conditioned on `Perpetuum.Server` — runs once per solution build, not once per project.
+- `ContinueOnError="true"` — build is never blocked. Machines without .NET 10 SDK or without `dotnet tool restore` silently skip graph generation.
+- Input scoped to `src/` — analyzes server source only, excludes `docs/`, `tools/`, generated files.
+- Output to `docs/graph/` — both JSON and HTML emitted in one pass.
+
+### Developer Setup
+
+After cloning (or after any `dotnet-tools.json` update):
+
+```
+dotnet tool restore
+```
+
+This installs graphify-dotnet locally. Subsequent builds regenerate the graph automatically.
+
+> **Note:** The registered tool command name (used in `dotnet tool run `) is defined in the package manifest, not the NuGet package ID. Verify the actual command name after `dotnet tool restore` by running `dotnet tool list`. Update `Directory.Build.targets` if the command name differs from `graphify-dotnet`.
+
+---
+
+## Output Files
+
+### `docs/graph/graph.json`
+
+Machine-readable structural graph. Nodes represent C# classes, interfaces, and namespaces. Edges represent inheritance, composition, and namespace imports. Louvain community detection groups related classes into clusters.
+
+Committed to git. Updated automatically on each `Perpetuum.Server` build by a developer with .NET 10 SDK installed.
+
+### `docs/graph/graph.html`
+
+Interactive vis.js browser visualization. Clickable nodes, search, community filtering. Operators open this file directly in a browser — no server required.
+
+Committed alongside `graph.json`.
+
+---
+
+## Claude Consumption
+
+New file: `.claude/knowledge/codebase-graph.md`
+
+```markdown
+# Codebase Dependency Graph
+
+Generated by graphify-dotnet. Regenerates automatically before each build of Perpetuum.Server.
+
+- Machine-readable graph: `docs/graph/graph.json`
+- Interactive visualization: `docs/graph/graph.html` (open in browser)
+
+Nodes: C# classes, interfaces, namespaces.
+Edges: inheritance, composition, namespace imports.
+Communities (Louvain clustering): related classes grouped together.
+
+Use this when:
+- Assessing impact of a change to a type (find its dependents in the JSON)
+- Navigating an unfamiliar subsystem (look up its community cluster)
+- Verifying no unintended cross-subsystem dependency is introduced
+```
+
+`architecture.md` gains a short "Graph Artifact" section pointing to `docs/graph/`.
+
+---
+
+## Soft-Fail Behavior
+
+The following conditions cause the target to silently skip without blocking the build:
+
+- .NET 10 SDK not installed on the machine
+- `dotnet tool restore` not yet run (tool not installed locally)
+- graphify-dotnet encounters a parsing error on a source file
+
+In all cases, any previously committed `docs/graph/` artifacts remain in place. The graph does not regress — it only fails to update.
+
+---
+
+## Scope Constraints
+
+- AST-only mode. AI semantic analysis (Azure OpenAI / Ollama / GitHub Copilot SDK) is out of scope for this integration.
+- No changes to project TFMs (net8.0 unchanged).
+- No CI changes in this phase.
+- `docs/graph/` is committed and kept up to date by developer builds, not CI.
+
+---
+
+## Deferred: Phase 2 — .NET 10 Migration
+
+The .NET 8→10 project migration is a separate workstream:
+- All `net8.0` entries updated to `net10.0`
+- NuGet dependency compatibility audit
+- BCL breaking change remediation
+- CI workflow SDK version update
+- `docs/STACK.md` updated
+
+Phase 2 has no dependency on Phase 1 and can be planned independently.
+
+---
+
+## Risks
+
+| Risk | Likelihood | Mitigation |
+|---|---|---|
+| graphify-dotnet CLI flags or tool command name differ from assumed | Medium | After `dotnet tool restore`, run `dotnet tool list` to confirm command name and `dotnet tool run graphify-dotnet --help` to confirm flag syntax; adjust `Directory.Build.targets` accordingly |
+| .NET 10 SDK not present on dev machines | Low-Medium | Soft-fail handles this; graph stays stale but build is unblocked |
+| Large codebase causes slow graph generation | Low | AST-only mode is fast; if slow, add an opt-out env var (`$(RunGraphify) != 'false'`) |
+| `graph.html` grows too large to commit | Low | graphify-dotnet is designed for this; monitor file size after first run |
+
+---
+
+## Manual Validation Steps
+
+1. Run `dotnet tool restore` from solution root — confirms tool installs without error.
+2. Build `Perpetuum.Server` — confirm `GenerateCodeGraph` target runs (check build output).
+3. Verify `docs/graph/graph.json` and `docs/graph/graph.html` are created/updated.
+4. Open `docs/graph/graph.html` in a browser — confirm interactive graph loads.
+5. Inspect `graph.json` — confirm C# classes and their relationships appear as nodes/edges.
+6. Commit `docs/graph/` — confirm Claude can reference the file path.
+7. Remove .NET 10 SDK (or rename tool manifest) and rebuild — confirm build succeeds with a warning, not a failure.