From 70b2feb792fcf4878119ab4f648fe8925c6e9e11 Mon Sep 17 00:00:00 2001 From: Meketreve <34199654+meketreve@users.noreply.github.com> Date: Thu, 13 Aug 2026 07:34:44 -0300 Subject: [PATCH 1/2] Move ISSUE-033 and ISSUE-034 to completed.md Both fixes are merged - PR #19 for ISSUE-033 and PR #20 for ISSUE-034 - so the entries are set to DONE and moved, per the Backlog Rules in CLAUDE.md. Each entry now records what actually shipped: the Proposed Fix section is replaced by a Fix section describing the change, a Files Changed section, and a note naming the merged PR. For ISSUE-034 the Fix also states which of the two options was taken for the two .claude/knowledge/architecture.md references - they were repointed at docs/codebase/ARCHITECTURE.md rather than creating the missing file. Also restores the --- separator between entries in issues.md. The three entries added in PR #18 were missing it, and removing two of them left ISSUE-035 and ISSUE-032 adjacent with no rule between them. Co-Authored-By: Claude Opus 5 --- docs/backlog/completed.md | 48 +++++++++++++++++++++++++++++++++++++++ docs/backlog/issues.md | 40 +------------------------------- 2 files changed, 49 insertions(+), 39 deletions(-) diff --git a/docs/backlog/completed.md b/docs/backlog/completed.md index ef4d31bb..c3fe4809 100644 --- a/docs/backlog/completed.md +++ b/docs/backlog/completed.md @@ -836,3 +836,51 @@ Enforced a same-IP gate on season activity recording so that a player running mu ### Notes Vendor market fills (no player counterparty) record without gate. `buyOrderPayBack` and `CashInOnSubmit` (no counterparty) left ungated. NAT false-positive limitation documented in spec. + +--- + +## ISSUE-034 - CLAUDE.md contains stale references that misdirect contributors + +Status: DONE +Priority: MEDIUM +Area: Documentation + +### Problem +Three sets of references in `CLAUDE.md` did not match the repository: the documented run command used a `--GameRoot` option that `Program.cs` does not define, eight `docs/` paths pointed at files that live under `docs/codebase/`, and `.claude/knowledge/architecture.md` was referenced twice but does not exist. + +### Impact +`CLAUDE.md` is the instruction file for agent-assisted work, so a wrong path or command is followed rather than questioned. The documented run command could not succeed, and ten path references resolved to nothing. + +### Fix +1. Run command changed to the positional form, `dotnet run -- ""`, matching `app.Argument("", ...)` in `src/Perpetuum.Server/Program.cs`. +2. The eight `docs/` paths prefixed with `codebase/` — six in Authoritative Documentation plus the repeats under Technical Debt Rules and Code Placement. +3. Both `.claude/knowledge/architecture.md` references repointed at `docs/codebase/ARCHITECTURE.md` rather than creating the missing file, so the architecture documentation keeps a single source of truth. + +### Files Changed +- `CLAUDE.md` — lines 44, 56, 77, 80, 83, 86, 89, 92, 222, 316, 331 as of `b8d2ec2` + +### Notes +Merged in PR #20. `--GameRoot` remains valid for `Perpetuum.ServerService2`, which reads `GameRoot` from `appsettings.json`, and was left alone. Every backticked path in the file was resolved against the working tree afterwards; `Commands.cs`, `completed.md` and `graph.json` still do not resolve because they are bare filenames used in prose, not paths. + +--- + +## ISSUE-033 - FreeRoamingPathFinder throws on presences with no flocks + +Status: DONE +Priority: LOW +Area: NPC AI / Logging + +### Problem +`TryGetMaxHomeRange` called `presence.Flocks.Max(f => f.HomeRange)` and `TryGetMinSlope` called `presence.Flocks.GetMembers().Min(m => m.Slope)`. On an empty sequence LINQ raises `InvalidOperationException: Sequence contains no elements`, which the surrounding `try/catch` swallowed after writing a full stack trace through `Logger.Exception`. + +### Impact +A presence with no flocks is a normal state, so each one emitted a stack trace during zone startup — exception handling used as ordinary control flow, and traces that make genuine faults harder to spot. + +### Fix +Project the value with `Select`, then supply the fallback with `DefaultIfEmpty` before aggregating. The fallbacks are the values the `catch` blocks already returned, so behaviour is unchanged: `10` before `Clamp(10, 40)` for the home range, `ZoneExtensions.MIN_SLOPE` for the slope. The `try/catch` and the `Logger.Exception` calls stay, still covering genuinely unexpected failures. + +### Files Changed +- `src/Perpetuum/Zones/NpcSystem/Presences/PathFinders/FreeRoamingPathFinder.cs` — `TryGetMaxHomeRange`, `TryGetMinSlope` + +### Notes +Merged in PR #19. Validated against a local P36 server, since there is no automated test suite: the pre-fix startup log carried 8 `Sequence contains no elements` traces, all from `TryGetMaxHomeRange`, and the post-fix log carries none while still spawning 6406 flock members and reaching `[Online]`. diff --git a/docs/backlog/issues.md b/docs/backlog/issues.md index db014977..539be98f 100644 --- a/docs/backlog/issues.md +++ b/docs/backlog/issues.md @@ -29,45 +29,7 @@ Reproduced against SQL Server 2022 Express, named instance, Windows integrated a `TrustServerCertificate=True` disables server certificate validation. It is appropriate for a local development instance only and must not be carried into a deployment where the connection leaves the machine. -## ISSUE-034 - CLAUDE.md contains stale references that misdirect contributors - -Status: TODO -Priority: MEDIUM -Area: Documentation - -### Problem -Three sets of references in `CLAUDE.md` do not match the repository: - -1. Build & Run documents `dotnet run -- --GameRoot ""`. `src/Perpetuum.Server/Program.cs` declares the game root as a positional argument via `app.Argument("", ...)`, so the option does not exist and the run fails with `Unrecognized option '--GameRoot'`. The working form is `dotnet run -- ""`. -2. Eight `docs/` references point at files that do not exist. Authoritative Documentation links `docs/CONCERNS.md` (line 77), `docs/CONVENTIONS.md` (80), `docs/INTEGRATIONS.md` (83), `docs/STACK.md` (86), `docs/STRUCTURE.md` (89) and `docs/TESTING.md` (92); Technical Debt Rules links `docs/CONCERNS.md` again (222) and Code Placement links `docs/STRUCTURE.md` again (316). All six files live under `docs/codebase/`. Only the `ARCHITECTURE.md` entry (74) already points there. -3. `.claude/knowledge/architecture.md` does not exist and is referenced twice: as the file to update when introducing major architectural changes (line 44), and as the architecture deep-dive in the Where to Edit table (331). `.claude/knowledge/` contains only `codebase-graph.md`. - -### Impact -`CLAUDE.md` is the instruction file for agent-assisted work, so a wrong path or command is followed rather than questioned. The documented run command cannot succeed, and ten path references resolve to nothing — eight under `docs/` and two under `.claude/knowledge/`. - -### Proposed Fix -Correct the run command to the positional form and prefix the eight `docs/` paths with `codebase/`. The two `.claude/knowledge/architecture.md` references need a maintainer decision: repoint them at `docs/codebase/ARCHITECTURE.md`, which already holds the architecture documentation, or create the missing file. - -### Notes -`--GameRoot` remains valid for `Perpetuum.ServerService2`, which reads `GameRoot` from `appsettings.json`; only the `Perpetuum.Server` console entry point takes it positionally. Line numbers are against `CLAUDE.md` at `b8d2ec2` (P36.7). `Commands.cs` and `completed.md` also appear in the file, but as bare filenames in prose rather than paths. - -## ISSUE-033 - FreeRoamingPathFinder throws on presences with no flocks - -Status: TODO -Priority: LOW -Area: NPC AI / Logging - -### Problem -`FreeRoamingPathFinder.TryGetMaxHomeRange` calls `presence.Flocks.Max(f => f.HomeRange)` and `TryGetMinSlope` calls `presence.Flocks.GetMembers().Min(m => m.Slope)`. When the sequence is empty, LINQ raises `InvalidOperationException: Sequence contains no elements`. The surrounding `try/catch` swallows it, writes a full stack trace through `Logger.Exception`, and returns the fallback value. - -### Impact -A presence with no flocks is a normal state, not a fault, so each one emits a stack trace during zone startup. Exception handling is used as ordinary control flow on a per-presence path, and the resulting traces make genuine faults harder to spot in the log. - -### Proposed Fix -Project the value and use `DefaultIfEmpty` so the empty case yields the fallback without throwing, keeping the `try/catch` for genuinely unexpected failures. - -### Notes -Observed during startup against a P36 database. Existing behaviour must be preserved: empty flocks yield `10` after `Clamp(10, 40)`, and empty members yield `ZoneExtensions.MIN_SLOPE`. +--- --- From 3cb8b8bc1951486de3851b40afffd8cc2caed8ba Mon Sep 17 00:00:00 2001 From: Meketreve <34199654+meketreve@users.noreply.github.com> Date: Thu, 13 Aug 2026 10:28:58 -0300 Subject: [PATCH 2/2] docs: correct the remaining --GameRoot references under docs/codebase PR #20 fixed the run command in CLAUDE.md, but ISSUE-034 had only surveyed that file. The same mistake sits in three files under docs/codebase/, which is the authoritative documentation set: - TESTING.md gives the manual-testing command as dotnet run -- --GameRoot "" - STACK.md describes McMaster.Extensions.CommandLineUtils as parsing a --GameRoot option - STRUCTURE.md describes Program.cs as parsing --GameRoot src/Perpetuum.Server/Program.cs declares the game root positionally, via app.Argument("", ...), so the option does not exist and the documented command fails with Unrecognized option '--GameRoot'. TESTING.md matters most of the three: the repository has no automated test suite, so running the server by hand is the only validation path a contributor has, and the command given for it could not work. Widen the ISSUE-034 entry in completed.md to cover these three files rather than closing it as done while the same defect remains in the docs it points contributors at. --GameRoot remains valid for Perpetuum.ServerService2, which reads GameRoot from appsettings.json, and is untouched. Five further occurrences under docs/superpowers/plans/ are dated records of plans already carried out and are left as written. Co-Authored-By: Claude Opus 5 --- docs/backlog/completed.md | 16 ++++++++++++++-- docs/codebase/STACK.md | 2 +- docs/codebase/STRUCTURE.md | 2 +- docs/codebase/TESTING.md | 2 +- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/docs/backlog/completed.md b/docs/backlog/completed.md index c3fe4809..83398833 100644 --- a/docs/backlog/completed.md +++ b/docs/backlog/completed.md @@ -839,7 +839,7 @@ Vendor market fills (no player counterparty) record without gate. `buyOrderPayBa --- -## ISSUE-034 - CLAUDE.md contains stale references that misdirect contributors +## ISSUE-034 - Stale references in CLAUDE.md and docs/codebase misdirect contributors Status: DONE Priority: MEDIUM @@ -848,19 +848,31 @@ Area: Documentation ### Problem Three sets of references in `CLAUDE.md` did not match the repository: the documented run command used a `--GameRoot` option that `Program.cs` does not define, eight `docs/` paths pointed at files that live under `docs/codebase/`, and `.claude/knowledge/architecture.md` was referenced twice but does not exist. +The same `--GameRoot` mistake also appeared in three files under `docs/codebase/`, which the original entry did not cover: the manual-testing command in `TESTING.md`, the CLI description in `STACK.md`, and the entry-point description in `STRUCTURE.md`. + ### Impact `CLAUDE.md` is the instruction file for agent-assisted work, so a wrong path or command is followed rather than questioned. The documented run command could not succeed, and ten path references resolved to nothing. +`docs/codebase/` is the authoritative documentation set, and `TESTING.md` is where a contributor looks for how to validate a change — with no automated test suite in the repository, running the server by hand is the only validation path there is, and the command given for it did not work. + ### Fix 1. Run command changed to the positional form, `dotnet run -- ""`, matching `app.Argument("", ...)` in `src/Perpetuum.Server/Program.cs`. 2. The eight `docs/` paths prefixed with `codebase/` — six in Authoritative Documentation plus the repeats under Technical Debt Rules and Code Placement. 3. Both `.claude/knowledge/architecture.md` references repointed at `docs/codebase/ARCHITECTURE.md` rather than creating the missing file, so the architecture documentation keeps a single source of truth. +4. The three `docs/codebase/` occurrences corrected: `TESTING.md` now shows the positional command, and `STACK.md` and `STRUCTURE.md` describe the argument as positional `` instead of an option. ### Files Changed - `CLAUDE.md` — lines 44, 56, 77, 80, 83, 86, 89, 92, 222, 316, 331 as of `b8d2ec2` +- `docs/codebase/TESTING.md` — line 34 as of `f9ddac2` +- `docs/codebase/STACK.md` — line 53 as of `f9ddac2` +- `docs/codebase/STRUCTURE.md` — line 194 as of `f9ddac2` ### Notes -Merged in PR #20. `--GameRoot` remains valid for `Perpetuum.ServerService2`, which reads `GameRoot` from `appsettings.json`, and was left alone. Every backticked path in the file was resolved against the working tree afterwards; `Commands.cs`, `completed.md` and `graph.json` still do not resolve because they are bare filenames used in prose, not paths. +The `CLAUDE.md` part merged in PR #20; the three `docs/codebase/` files were corrected afterwards, in the same change that moved this entry here. + +`--GameRoot` remains valid for `Perpetuum.ServerService2`, which reads `GameRoot` from `appsettings.json`, and was left alone. Every backticked path in `CLAUDE.md` was resolved against the working tree afterwards; `Commands.cs`, `completed.md` and `graph.json` still do not resolve because they are bare filenames used in prose, not paths. + +Five further occurrences of the old command survive under `docs/superpowers/plans/`. Those are dated records of plans that were already carried out, so they were left untouched rather than rewritten after the fact. --- diff --git a/docs/codebase/STACK.md b/docs/codebase/STACK.md index 40d2f2a9..b2500cbd 100644 --- a/docs/codebase/STACK.md +++ b/docs/codebase/STACK.md @@ -50,7 +50,7 @@ - `System.Text.RegularExpressions` 4.3.1 — regex utilities (referenced in all projects) **CLI:** -- `McMaster.Extensions.CommandLineUtils` 4.1.1 — `--GameRoot` argument parsing in `src/Perpetuum.Server/Program.cs` +- `McMaster.Extensions.CommandLineUtils` 4.1.1 — positional `` argument parsing in `src/Perpetuum.Server/Program.cs` **Crypto:** - RC4 stream cipher: custom implementation at `src/Perpetuum/Rc4.cs` diff --git a/docs/codebase/STRUCTURE.md b/docs/codebase/STRUCTURE.md index 89388748..ee1bae3b 100644 --- a/docs/codebase/STRUCTURE.md +++ b/docs/codebase/STRUCTURE.md @@ -191,7 +191,7 @@ src/Perpetuum.RequestHandlers/ ## Key Files **Entry Points:** -- `src/Perpetuum.Server/Program.cs` — console entry; parses `--GameRoot`, calls `bootstrapper.Init/Start` +- `src/Perpetuum.Server/Program.cs` — console entry; takes the game root as a positional `` argument, calls `bootstrapper.Init/Start` - `src/Perpetuum.ServerService2/` — Windows service wrapper for the same bootstrapper **Bootstrap:** diff --git a/docs/codebase/TESTING.md b/docs/codebase/TESTING.md index 4600fe67..9b8f2829 100644 --- a/docs/codebase/TESTING.md +++ b/docs/codebase/TESTING.md @@ -31,7 +31,7 @@ The team tests by running the server locally against a configured `GameRoot`: ```bash cd src/Perpetuum.Server -dotnet run -- --GameRoot "E:\PerpetuumServer2\data" +dotnet run -- "E:\PerpetuumServer2\data" ``` Manual verification involves: