NEO-64: add implementation plan for gather telemetry hooks.
parent
052dd7bc8a
commit
f39d12a093
|
|
@ -0,0 +1,103 @@
|
|||
# NEO-64 — Implementation plan
|
||||
|
||||
## Story reference
|
||||
|
||||
| Field | Value |
|
||||
|--------|--------|
|
||||
| **Key** | NEO-64 |
|
||||
| **Title** | E3.M1: resource_gathered / gather_node_depleted telemetry hook sites |
|
||||
| **Linear** | https://linear.app/neon-sprawl/issue/NEO-64/e3m1-resource-gathered-gather-node-depleted-telemetry-hook-sites |
|
||||
| **Module** | [E3.M1 — ResourceNodeAndGatherLoop](../decomposition/modules/E3_M1_ResourceNodeAndGatherLoop.md) · Epic 3 Slice 2 · backlog **E3M1-08** |
|
||||
| **Branch** | `NEO-64-e3m1-resource-gathered-gather-node-depleted-telemetry-hooks` |
|
||||
| **Blocked by** | [NEO-62](https://linear.app/neon-sprawl/issue/NEO-62) — `GatherOperations` + `GatherResult` (**Done** on `main`); [NEO-63](https://linear.app/neon-sprawl/issue/NEO-63) — interact gather wiring (**Done** on `main`). |
|
||||
| **Pattern** | [NEO-49](https://linear.app/neon-sprawl/issue/NEO-49) / [NEO-56](https://linear.app/neon-sprawl/issue/NEO-56) — comment-only engine anchors; [NEO-30](https://linear.app/neon-sprawl/issue/NEO-30) — event name + `TODO(E9.M1)` |
|
||||
|
||||
## Kickoff clarifications
|
||||
|
||||
| Topic | Question | Agent recommendation | Answer |
|
||||
|--------|----------|----------------------|--------|
|
||||
| **Runtime behavior** | Comments-only vs dev `ILogger`? | **Comments-only** — `TODO(E9.M1)`; no production logging (NEO-49/56 precedent). | **Adopted** (repo precedent; not asked). |
|
||||
| **Hook anchor** | Engine only vs engine + `InteractionApi`? | **Engine only** in **`GatherOperations.TryGather`** — HTTP calls engine; no duplicate API-layer hooks (NEO-56 precedent). | **Adopted** (repo precedent; not asked). |
|
||||
| **`gather_node_depleted` timing** | Success transition vs also pre-gather deny? | **Success transition only** — hook when a successful gather drives **`remainingGathers`** to **0** after depletion commit; not on pre-gather **`node_depleted`** deny. | **User:** success transition only. |
|
||||
| **Manual QA doc** | `docs/manual-qa/NEO-64.md`? | **Yes** — NEO-49/56 verification pattern (comments + no behavior change). | **Adopted** (repo convention). |
|
||||
|
||||
## Goal, scope, and out-of-scope
|
||||
|
||||
**Goal:** Document and place **comment-only hook sites** on the server-authoritative gather path for future E9.M1 catalog events **`resource_gathered`** and **`gather_node_depleted`**. Align with Epic 3 Slice 2 telemetry vocabulary ([epic_03 — Slice 2](../decomposition/epics/epic_03_crafting_economy.md#epic-3-slice-2)).
|
||||
|
||||
**In scope (from Linear + [E3M1-08](E3M1-prototype-backlog.md#e3m1-08--resource_gathered--gather_node_depleted-telemetry-hook-sites)):**
|
||||
|
||||
- Hook placement in **`GatherOperations.TryGather`** with **`TODO(E9.M1)`** comments.
|
||||
- **`server/README.md`** gather subsection + [E3_M1 module](../decomposition/modules/E3_M1_ResourceNodeAndGatherLoop.md) hook note.
|
||||
- **`docs/manual-qa/NEO-64.md`** — verify comments + no behavior/API change.
|
||||
- E3M1 backlog + alignment register updates when implementation completes.
|
||||
|
||||
**Out of scope (from Linear):**
|
||||
|
||||
- Telemetry ingest, dashboards (**E9.M1**).
|
||||
- `ILogger` / metrics / dev-only log lines.
|
||||
- Duplicate hook comments in **`InteractionApi`** (NEO-56 engine-only precedent).
|
||||
- **`gather_node_depleted`** on pre-gather depletion deny or interact deny passthrough (kickoff decision).
|
||||
|
||||
## Acceptance criteria checklist
|
||||
|
||||
- [ ] Hook sites documented in code and `server/README.md`.
|
||||
- [ ] Matches Epic 3 Slice 2 telemetry vocabulary (`resource_gathered`, `gather_node_depleted`).
|
||||
|
||||
## Technical approach
|
||||
|
||||
1. **Authoritative surface:** **`GatherOperations.TryGather`** — all gather side effects (inventory → XP → depletion) funnel here; **`InteractionApi`** delegates **`resource_node`** interact without duplicating hooks.
|
||||
|
||||
2. **Hook site A — `resource_gathered`:** Immediately before the successful **`GatherResult`** return (after depletion commit succeeds):
|
||||
- Comment block names future E9.M1 event **`resource_gathered`**.
|
||||
- **`TODO(E9.M1): catalog emit`** (NEO-49 / NEO-56 style).
|
||||
- Planned payload fields: `playerId`, `interactableId` (node instance key), `itemId`, `quantity` (from **`GatherGrantApplied`**), `skillId` + `xpAmount` + `sourceKind` (from **`GatherXpGrantSummary`**), `remainingGathers` after commit.
|
||||
|
||||
3. **Hook site B — `gather_node_depleted`:** On the same success path, when **`depletionOutcome.Snapshot.RemainingGathers == 0`** (node exhausted by this gather):
|
||||
- Comment block names future E9.M1 event **`gather_node_depleted`**.
|
||||
- **`TODO(E9.M1): catalog emit`** — emit **once** when capacity transitions to zero via successful gather (not on pre-gather **`node_depleted`** deny).
|
||||
- Planned payload fields: `interactableId`, optional `playerId` (last gatherer), `maxGathers` from definition if needed at E9.M1 wiring time.
|
||||
|
||||
4. **Cross-references (minimal):**
|
||||
- Update **`GatherResult.cs`** xml summary → hook sites in **`TryGather`**.
|
||||
- **`GatherOperations`** class summary → NEO-64 telemetry hook anchor.
|
||||
- **`server/README.md`:** new **NEO-64 telemetry hooks** subsection under gather engine (after NEO-62 block).
|
||||
- **`E3_M1_ResourceNodeAndGatherLoop.md`:** NEO-64 landed line when complete.
|
||||
- **`documentation_and_implementation_alignment.md`** + **`module_dependency_register.md`:** E3.M1 row — E3M1-08 complete; module **Ready** when all Slice 2 backlog lands.
|
||||
- **`E3M1-prototype-backlog.md`:** E3M1-08 checkboxes + landed note.
|
||||
|
||||
5. **NEO-56 interaction:** Successful gather already triggers **`item_created`** inside **`PlayerInventoryOperations.TryAddStack`**; **`resource_gathered`** is the gather-funnel catalog event at the orchestration layer (analogous to cast accept vs ability-specific events).
|
||||
|
||||
## Files to add
|
||||
|
||||
| Path | Purpose |
|
||||
|------|---------|
|
||||
| `docs/manual-qa/NEO-64.md` | Manual QA: verify comment blocks + no behavior/API change. |
|
||||
| `docs/plans/NEO-64-implementation-plan.md` | This plan. |
|
||||
|
||||
## Files to modify
|
||||
|
||||
| Path | Rationale |
|
||||
|------|-----------|
|
||||
| `server/NeonSprawl.Server/Game/Gathering/GatherOperations.cs` | **NEO-64:** comment-only **`resource_gathered`** + **`gather_node_depleted`** hook sites on success path. |
|
||||
| `server/NeonSprawl.Server/Game/Gathering/GatherResult.cs` | Cross-reference hook anchor in type summary (no behavior change). |
|
||||
| `server/README.md` | Document gather telemetry hook placement (NEO-64). |
|
||||
| `docs/decomposition/modules/E3_M1_ResourceNodeAndGatherLoop.md` | Implementation snapshot: NEO-64 telemetry hooks landed. |
|
||||
| `docs/decomposition/modules/documentation_and_implementation_alignment.md` | E3.M1 row: NEO-64 hook sites. |
|
||||
| `docs/decomposition/modules/module_dependency_register.md` | E3.M1 note — E3M1-08 complete; module status **Ready**. |
|
||||
| `docs/plans/E3M1-prototype-backlog.md` | E3M1-08 checkboxes + landed note. |
|
||||
|
||||
## Tests
|
||||
|
||||
| Test file | What it covers |
|
||||
|-----------|----------------|
|
||||
| *(none added or changed)* | Comments-only change; no behavior or wire contract change. Regression: `dotnet test NeonSprawl.sln` (existing **`GatherOperationsTests`** + **`InteractionResourceNodeGatherIntegrationTests`** unchanged). Manual verification: **`docs/manual-qa/NEO-64.md`**. |
|
||||
|
||||
## Open questions / risks
|
||||
|
||||
| Question / risk | Agent recommendation | Status |
|
||||
|-----------------|----------------------|--------|
|
||||
| **Overlap with NEO-56 `item_created`** | Keep both — **`item_created`** at inventory layer; **`resource_gathered`** at gather orchestration (E9.M1 can correlate or sample). | **adopted** |
|
||||
| **Pre-gather depletion deny telemetry** | No **`gather_node_depleted`** hook on deny; interact **`node_depleted`** **`reasonCode`** suffices until E9.M1 defines a separate deny funnel event. | **adopted** (kickoff) |
|
||||
|
||||
None blocking.
|
||||
Loading…
Reference in New Issue