neon-sprawl/docs/reviews/2026-05-24-NEO-64.md

55 lines
5.0 KiB
Markdown
Raw 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.

# Code review — NEO-64 gather telemetry hook sites
**Date:** 2026-05-24
**Scope:** Branch `NEO-64-e3m1-resource-gathered-gather-node-depleted-telemetry-hooks` · commits `f39d12a``847cda9` vs `origin/main`
**Base:** `origin/main`
## Verdict
**Approve with nits**
## Summary
NEO-64 adds **comment-only** E9.M1 telemetry hook anchors in **`GatherOperations.TryGather`** for future catalog events **`resource_gathered`** (every successful gather after inventory + XP + depletion commit) and **`gather_node_depleted`** (when that success drives **`remainingGathers`** to **0**, not on pre-gather **`node_depleted`** deny). The change follows NEO-49/NEO-56 precedent: **`TODO(E9.M1)`** markers, planned payload fields, no **`ILogger`** or ingest, engine-only placement (no duplicate hooks in **`InteractionApi`**). Docs close out Epic 3 Slice 2 / E3.M1 backlog (**Ready**). Risk is very low — no runtime behavior, wire contract, or test changes; **`remainingAfterGather`** local is a readability refactor only.
## Documentation checked
| Document | Result |
|----------|--------|
| [`docs/plans/NEO-64-implementation-plan.md`](../plans/NEO-64-implementation-plan.md) | **Matches** — comments-only, engine-only anchor, success-path timing, kickoff decisions (no interact deny hook, no ILogger), all planned file touches, acceptance checklist complete. |
| [`docs/plans/E3M1-prototype-backlog.md`](../plans/E3M1-prototype-backlog.md) | **Matches** — E3M1-08 checkboxes + landed note; Slice 2 backlog complete. Template line “interact deny branch if applicable” superseded by kickoff (engine-only) — no implementation conflict. |
| [`docs/decomposition/modules/E3_M1_ResourceNodeAndGatherLoop.md`](../decomposition/modules/E3_M1_ResourceNodeAndGatherLoop.md) | **Matches** — NEO-64 hook bullet, module **Ready**, gather orchestration authority unchanged. |
| [`docs/decomposition/modules/documentation_and_implementation_alignment.md`](../decomposition/modules/documentation_and_implementation_alignment.md) | **Matches** — E3.M1 row **Ready** with NEO-64 landed note; E3M1-01E3M1-08 complete. |
| [`docs/decomposition/modules/module_dependency_register.md`](../decomposition/modules/module_dependency_register.md) | **Matches** — E3.M1 row **Ready**; **E3.M1 note** includes NEO-64 / E3M1-08. |
| [`docs/decomposition/epics/epic_03_crafting_economy.md`](../decomposition/epics/epic_03_crafting_economy.md) | **Matches** — Slice 2 vocabulary `resource_gathered`, `gather_node_depleted`. |
| [`docs/decomposition/modules/client_server_authority.md`](../decomposition/modules/client_server_authority.md) | **N/A** — no authority boundary change. |
| [`docs/manual-qa/NEO-64.md`](../manual-qa/NEO-64.md) | **Matches** — code-review checklist, regression command, optional Bruno sanity. |
| [`server/README.md`](../../server/README.md) | **Matches** — NEO-64 paragraph under gather engine (NEO-62): event names, timing, NEO-56 `item_created` cross-ref, manual QA + plan links. |
Register/tracking: E3.M1 **Ready** and alignment row updates are appropriate — Slice 2 backlog is complete.
## Blocking issues
None.
## Suggestions
1. ~~**Conditional structure for `gather_node_depleted` (optional)** — NEO-40 nests the **`level_up`** hook inside `if (nextLevel > prevLevel)`. Here **`gather_node_depleted`** documents “when **`remainingAfterGather == 0`**” but sits on the unconditional success path. Consider a brief commented guard (e.g. `// if (remainingAfterGather == 0) { … emit gather_node_depleted … }`) so E9.M1 wiring mirrors the **`level_up`** pattern and avoids accidental unconditional emit. Low priority — comment text is already explicit.~~ **Done.****`gather_node_depleted`** hook comments nested in `if (remainingAfterGather == 0)`.
2. ~~**Backlog template wording (optional)** — E3M1-08 in [`E3M1-prototype-backlog.md`](../plans/E3M1-prototype-backlog.md) still lists “interact deny branch if applicable” in **In scope**; kickoff chose engine-only. A one-line “deny branch: out of scope (NEO-64 kickoff)” under E3M1-08 would reduce future misreads.~~ **Done.**
## Nits
- ~~Nit: README NEO-64 content is a bold paragraph under **Gather engine (NEO-62)** rather than a separate `### Gather telemetry hooks (NEO-64)` heading with its own anchor; module doc links to `#gather-engine-neo-62` — acceptable, optional heading if you want parity with NEO-49s dedicated README subsection.~~ **Done.** — dedicated `### Gather telemetry hooks (NEO-64)` subsection; module doc link updated.
- Nit: **`gather_node_depleted`** comment block could repeat **`TODO(E9.M1): catalog emit`** on its own line (it does — same style as **`resource_gathered`**). No change needed.
## Verification
```bash
cd /home/don/neon-sprawl && dotnet test NeonSprawl.sln
# Passed! Failed: 0, Passed: 292
```
Manual: walk [`docs/manual-qa/NEO-64.md`](../manual-qa/NEO-64.md) code-review checklist; optional Bruno `bruno/neon-sprawl-server/interaction/` against a running server to confirm gather behavior unchanged.