neon-sprawl/docs/reviews/2026-04-25-NEO-29.md

5.6 KiB

Code review — NEO-29

  • Date: 2026-04-25
  • Scope: Branch NEO-29-hotbarloadout-v1-contract-baseline-persistence-path (origin/main...HEAD)
  • Base: origin/main
  • Follow-up: Re-review after NEO-29: apply code review follow-ups and subsequent test refactor commits (d25d7d0..HEAD).

Verdict

Approve with nits.

Summary

The earlier documentation-alignment and lower-bound slot test suggestions were addressed correctly. E1.M4 status tracking now matches implementation state, the slotIndex < 0 deny-path test was added, and the client GDScript parse regression in hotbar_loadout_client_test.gd is now fixed. Refactored server AAA tests run cleanly in the targeted suites, and the hotbar client test suite now executes successfully. Remaining risk is low and limited to test-run warning noise from the headless Godot runner rather than functional test failures.

Documentation checked

  • docs/plans/NEO-29-implementation-plan.mdmatches (scope, API shape, persistence policy, deny reasons, tests/docs artifacts all present).
  • docs/plans/E1M4-prototype-backlog.mdmatches (E1M4-01 slice framing and NEO-29 implementation note are consistent).
  • docs/decomposition/modules/E1_M4_AbilityInputScaffold.mdmatches (summary status and implementation snapshot now align with landed NEO-29 work).
  • docs/decomposition/modules/module_dependency_register.mdmatches (E1.M4 row and note now show In Progress).
  • docs/decomposition/modules/documentation_and_implementation_alignment.mdmatches (tracking table now includes E1.M4 implementation snapshot/pointers).
  • docs/decomposition/modules/contracts.mdmatches for prototype scope (JSON/HTTP spike is acceptable for early slice; versioned envelope and stable reason codes are documented).
  • docs/decomposition/modules/client_server_authority.mdmatches (server remains authority for persistent gameplay-relevant loadout state; client acts as view/sync).

Register/tracking follow-up from the first pass is now closed.

Blocking issues

None.

Suggestions

  1. Update decomposition status tracking for E1.M4 from Planned to In Progress in the register/module summary (and corresponding tracking inventory) so docs comply with documentation_and_implementation_alignment.md and do not under-report shipped progress. Done. Updated docs/decomposition/modules/module_dependency_register.md (row + note), docs/decomposition/modules/E1_M4_AbilityInputScaffold.md (summary status), and docs/decomposition/modules/documentation_and_implementation_alignment.md (new E1.M4 tracking row).
  2. Several C# test files now place AAA markers inconsistently (e.g., // Act above // Arrange and inline comment placement on brace lines). This does not break runtime behavior, but it undermines the readability goal of the AAA refactor and conflicts with the documented template/order in server/NeonSprawl.Server.Tests/TestTemplates/AAA_TEST_METHOD_TEMPLATE.cs.txt. Done. Normalized affected suites so AAA markers are consistently ordered and placed on their own lines in server/NeonSprawl.Server.Tests/Game/Interaction/HorizontalReachTests.cs, server/NeonSprawl.Server.Tests/Game/Interaction/InteractionApiTests.cs, server/NeonSprawl.Server.Tests/Game/PositionState/MoveCommandValidationTests.cs, server/NeonSprawl.Server.Tests/Game/Targeting/PlayerTargetStateReaderTests.cs, and server/NeonSprawl.Server.Tests/Game/Targeting/TargetingApiTests.cs.

Nits

  • Nit: Consider adding one API test for slotIndex < 0 deny parity with the existing slotIndex == 8 test, to lock the lower-bound contract explicitly. Done. Added PostHotbarLoadout_ShouldDenyNegativeSlot_WithReasonCode in server/NeonSprawl.Server.Tests/Game/AbilityInput/HotbarLoadoutApiTests.cs.

Verification

  • dotnet test NeonSprawl.sln --filter "FullyQualifiedName~HotbarLoadoutApiTests"
  • dotnet test NeonSprawl.sln --filter "FullyQualifiedName~HotbarLoadoutPersistenceIntegrationTests"
  • godot --headless --path client -s res://addons/gdUnit4/bin/GdUnitCmdTool.gd --ignoreHeadlessMode -a res://test/hotbar_loadout_client_test.gd
  • Manual checklist: docs/manual-qa/NEO-29.md
  • Follow-up rerun (re-review):
    • dotnet test NeonSprawl.sln --filter "FullyQualifiedName~HotbarLoadoutApiTests|FullyQualifiedName~HotbarLoadoutPersistenceIntegrationTests|FullyQualifiedName~TargetingApiTests|FullyQualifiedName~InteractionApiTests|FullyQualifiedName~MoveCommandApiTests|FullyQualifiedName~MoveCommandValidationTests|FullyQualifiedName~MoveStreamApiTests|FullyQualifiedName~PlayerTargetStateReaderTests|FullyQualifiedName~HorizontalReachTests|FullyQualifiedName~InteractablesWorldApiTests" (71 passed)
    • godot --headless --path . -s res://addons/gdUnit4/bin/GdUnitCmdTool.gd --ignoreHeadlessMode -a res://test/hotbar_loadout_client_test.gd (parse/type error in client/test/hotbar_loadout_client_test.gd)
  • Final rerun (latest working tree):
    • dotnet test NeonSprawl.sln --filter "FullyQualifiedName~HotbarLoadoutApiTests|FullyQualifiedName~HotbarLoadoutPersistenceIntegrationTests|FullyQualifiedName~TargetingApiTests|FullyQualifiedName~InteractionApiTests|FullyQualifiedName~MoveCommandApiTests|FullyQualifiedName~MoveCommandValidationTests|FullyQualifiedName~MoveStreamApiTests|FullyQualifiedName~PlayerTargetStateReaderTests|FullyQualifiedName~HorizontalReachTests|FullyQualifiedName~InteractablesWorldApiTests" (71 passed)
    • godot --headless --path . -s res://addons/gdUnit4/bin/GdUnitCmdTool.gd --ignoreHeadlessMode -a res://test/hotbar_loadout_client_test.gd (6 passed; runner still prints non-fatal warning/error noise at shutdown)