neon-sprawl/docs/plans/NEO-63-implementation-plan.md

91 lines
6.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# NEO-63 — Implementation plan
## Story reference
| Field | Value |
|--------|--------|
| **Key** | NEO-63 |
| **Title** | E3.M1: Interact path integration + registry expansion + Bruno |
| **Linear** | https://linear.app/neon-sprawl/issue/NEO-63/e3m1-interact-path-integration-registry-expansion-bruno |
| **Module** | [E3.M1 — ResourceNodeAndGatherLoop](../decomposition/modules/E3_M1_ResourceNodeAndGatherLoop.md) · Epic 3 Slice 2 · backlog **E3M1-07** |
| **Branch** | `NEO-63-e3m1-interact-path-integration-registry-expansion-bruno` |
| **Precursors** | [NEO-62](https://linear.app/neon-sprawl/issue/NEO-62) — `GatherOperations` + `GatherResult` (**Done** on story branch); [NEO-41](https://linear.app/neon-sprawl/issue/NEO-41) — inline XP on interact (superseded) |
## Kickoff clarifications
| Topic | Question | Agent recommendation | Answer |
|--------|----------|----------------------|--------|
| **New node anchors** | X/Z for beta, gamma, delta? | **Beta (18, 6)**, **gamma (12, 0)**, **delta (18, 0)** — spread from alpha **(12, 6)** and terminal **(0, 0)**, same radius **3**. | **Adopted** (no blocking questions at kickoff; user said **begin**). |
| **Gather deny on interact** | `Allowed: false` + `reasonCode` vs NEO-41 silent success? | **`Allowed: false`** + passthrough gather **`reasonCode`** per E3M1-07 backlog. | **Adopted**. |
| **InteractionResponse payload** | Extend with gather fields? | **Keep placeholder** — verify via GET inventory / skill-progression (module doc). | **Adopted**. |
## Goal, scope, and out-of-scope
**Goal:** Wire **`POST …/interact`** **`resource_node`** path to **`GatherOperations`**; register **four** prototype nodes; Bruno + manual QA for gather → inventory and depletion deny.
**In scope:** `InteractionApi`, `PrototypeInteractableRegistry` expansion, integration tests, Bruno, README, manual QA.
**Out of scope:** Godot HUD, gather HTTP route, telemetry hooks (NEO-64).
## Acceptance criteria checklist
- [x] In-range interact on fresh node increases inventory quantity and **`salvage`** XP.
- [x] Depleted node returns **`node_depleted`** without inventory or XP change.
- [x] Terminal interact unchanged (no gather side effects).
- [x] Bruno documents happy path + depletion deny for at least one node.
## Technical approach
1. **`InteractionApi`:** On **`resource_node`** kind after range check, call **`GatherOperations.TryGather`**. Success → **`Allowed: true`**; deny → **`Allowed: false`** + **`ReasonCode`** from **`GatherResult`**. Remove NEO-41 inline **`SkillProgressionGrantOperations`** block.
2. **Registry:** Add beta/gamma/delta ids + anchors (see kickoff table). **`GET …/interactables`** returns **5** rows (terminal + four nodes).
3. **Tests:** New **`InteractionResourceNodeGatherIntegrationTests`** — inventory + XP success, depletion deny, terminal control, stub-registry deny. Update **`InteractablesWorldApiTests`** for four nodes. Trim NEO-41 XP-only defensive test (migrated to integration deny test). Fix **`SalvageActivityDeniedRegistryWebApplicationFactory`** for gather DI (items + resource nodes + inventory + instance stores).
4. **Bruno:** Update alpha gather request; add gather → GET inventory; add depletion deny (pre-request 10 gathers).
5. **Docs:** README interaction reason codes + gather subsection; E3.M1 module freeze table anchors; alignment + backlog checkboxes.
## Files to add
| Path | Purpose |
|------|---------|
| `server/NeonSprawl.Server.Tests/Game/Interaction/InteractionResourceNodeGatherIntegrationTests.cs` | HTTP integration: inventory, XP, depletion, terminal, deny registry. |
| `bruno/neon-sprawl-server/interaction/Post interact gather then get inventory.bru` | Happy path: interact + assert scrap in bag. |
| `bruno/neon-sprawl-server/interaction/Post interact depleted node deny.bru` | Pre-loop 10 gathers on **`prototype_urban_bulk_delta`** (isolated from alpha requests earlier in collection); 11th **`node_depleted`**. |
| `docs/manual-qa/NEO-63.md` | curl gather → inventory + depletion deny. |
| `docs/plans/NEO-63-implementation-plan.md` | This plan. |
## Files to modify
| Path | Rationale |
|------|-----------|
| `server/NeonSprawl.Server/Game/Interaction/InteractionApi.cs` | Delegate **`resource_node`** to **`GatherOperations`**; map denies. |
| `server/NeonSprawl.Server/Game/Interaction/PrototypeInteractableRegistry.cs` | Three new node anchors + registry entries. |
| `server/NeonSprawl.Server.Tests/Game/Interaction/InteractablesWorldApiTests.cs` | Assert **5** interactables + new anchor coords. |
| `server/NeonSprawl.Server.Tests/Game/Interaction/InteractionResourceNodeGatherXpTests.cs` | Remove obsolete NEO-41 silent-deny test; keep terminal + XP smoke. |
| `server/NeonSprawl.Server.Tests/Game/Interaction/SalvageActivityDeniedRegistryWebApplicationFactory.cs` | Full in-memory gather dependencies for deny test host. |
| `bruno/neon-sprawl-server/interaction/Post interact prototype resource node gather.bru` | NEO-63 docs (inventory + XP via gather engine). |
| `server/README.md` | Gather via interact; reason codes; four anchors. |
| `docs/decomposition/modules/E3_M1_ResourceNodeAndGatherLoop.md` | Anchor coords; NEO-63 slice bullet. |
| `docs/decomposition/modules/documentation_and_implementation_alignment.md` | E3.M1 row — NEO-63 landed. |
| `docs/decomposition/modules/module_dependency_register.md` | E3.M1 note — E3M1-07 complete. |
| `docs/plans/E3M1-prototype-backlog.md` | E3M1-07 checkboxes. |
## Tests
| Test file | What it covers |
|-----------|----------------|
| `InteractionResourceNodeGatherIntegrationTests.cs` | Success: +1 scrap, +10 salvage XP. Depletion: 10 gathers then **`node_depleted`**. Terminal: no side effects. Stub registry: deny + no grants. |
| `InteractablesWorldApiTests.cs` | **5** descriptors; beta/gamma/delta anchors. |
| `InteractionResourceNodeGatherXpTests.cs` | Terminal + alpha XP smoke (regression). |
## Open questions / risks
| Question / risk | Agent recommendation | Status |
|-----------------|----------------------|--------|
| **Branch stacks NEO-62** | PR base includes gather engine commits until NEO-62 merges. | **adopted** |
| **Client world props** | Godot **`interactable_world_builder`** picks up new ids from GET; no scene edit required for server QA. | **deferred** |
None blocking.