6.2 KiB
NEO-30 — Implementation plan
Story reference
| Field | Value |
|---|---|
| Key | NEO-30 |
| Title | E1M4-05: Slice 3 telemetry hooks for cast funnel |
| Linear | NEO-30 |
| Slug | E1M4-05 |
| Git branch | NEO-30-cast-funnel-telemetry-hooks |
| Parent context | E1M4 prototype backlog · E1.M4 — AbilityInputScaffold |
| Decomposition | Epic 1 Slice 3 — telemetry hooks; E9.M1 — TelemetryEventSchema (deferred catalog) |
Kickoff clarifications
- Docs scope (resolved): Update
docs/decomposition/modules/E1_M4_AbilityInputScaffold.mdanddocs/decomposition/modules/documentation_and_implementation_alignment.md(E1.M4 snapshot row) so hook locations and E9.M1 deferrals are discoverable from module + alignment table. - Server hook style (resolved): Comment-only hook sites in
AbilityCastApi(plusTODO(E9.M1)), no new server runtime logging — matches NEO-27 pattern, avoids duplicate noise with client dev prints/warnings and keeps PII/log-policy questions out of this slice. - Why no further blocking questions: Linear goal, in/out of scope, and acceptance criteria are explicit; cast HTTP + client hook behavior already exists from NEO-31/NEO-28.
Goal, scope, and out-of-scope
Goal: Complete Slice 3 telemetry hook sites for product names ability_cast_requested and ability_cast_denied (with reason metadata in comments / existing dev surfaces), and TODO(E9.M1) alignment until catalog/schema exists.
In scope
- Add or verify hook-site documentation on the server cast funnel (
POST /game/players/{id}/ability-cast): whereability_cast_requested(successful intent / accept path) andability_cast_denied(each deny branch with stablereasonCode) would attach for E9.M1 ingest — comments only, no production pipeline. - Payload notes in those comments: player id (route),
slotIndex,abilityId,targetId, and denyreasonCode(and note HTTP 400/404 paths are not Slice 3 “denied cast” JSON — noAbilityCastResponse). - Client: verify existing dev
print/push_warning/ HUD path still matches vocabulary from NEO-31 / NEO-28; tighten comments only if anything drifted.
Out of scope
- Production telemetry ingest, dashboards, retention (per Linear).
- New OpenTelemetry / structured server logs for this story (explicit kickoff decision).
Acceptance criteria checklist
- Hook names match Epic 1 Slice 3 telemetry vocabulary (
ability_cast_requested,ability_cast_denied). - Denied cast hook path carries a non-empty
reasonCodeonAbilityCastResponsedenies (already enforced by server + tests; verify + document in module plan). - Module doc +
documentation_and_implementation_alignment.mdreference where hooks are emitted / annotated and what remains deferred to E9.M1.
Technical approach
-
AbilityCastApi.cs— At the single map handler: document authoritative server hook sites — e.g. after validation passes and before returningAccepted: trueas the futureability_cast_requestedemit point; eachResults.Jsondeny as a futureability_cast_deniedemit point with the samereasonCodestring already returned. Note payload fields for catalog rows.TODO(E9.M1)on each site. -
Client (
main.gd,ability_cast_client.gd) — Confirmability_cast_requestedonly fires when POST is queued (request_cast→true) andability_cast_deniedwarning includesreasonCodeon JSON deny; align comment blocks with server anchor paths if needed. -
Docs —
E1_M4_AbilityInputScaffold.md: implementation snapshot + Linear table row E1M4-05 → NEO-30 (replace TBD).documentation_and_implementation_alignment.md: E1.M4 row cites NEO-30 and “telemetry hook sites” for cast funnel (still no ingest). -
Optional README — One-line under server “Ability cast” if it helps discoverability without duplicating the module doc.
Files to add
| Path | Rationale |
|---|---|
docs/manual-qa/NEO-30.md |
Thin checklist: confirm Godot Output / HUD still matches hook vocabulary after doc-only server changes; points to NEO-28/NEO-31 steps where behavior is shared. |
Files to modify
| Path | Rationale |
|---|---|
server/NeonSprawl.Server/Game/AbilityInput/AbilityCastApi.cs |
NEO-30: comment-only Slice 3 hook sites + payload notes + TODO(E9.M1) on accept and each deny branch. |
client/scripts/main.gd |
Verify/update comment block for ability_cast_requested / cross-reference server hook file if useful. |
client/scripts/ability_cast_client.gd |
Verify/update ability_cast_denied hook comment + TODO(E9.M1) next to warning emit. |
docs/decomposition/modules/E1_M4_AbilityInputScaffold.md |
Snapshot + E1M4-05 Linear link; source anchors for cast telemetry hooks. |
docs/decomposition/modules/documentation_and_implementation_alignment.md |
E1.M4 row: NEO-30 telemetry hook sites for cast funnel. |
server/README.md |
Optional one-line under Ability cast: hook sites documented in AbilityCastApi (NEO-30). |
Tests
| File | Action |
|---|---|
server/NeonSprawl.Server.Tests/Game/AbilityInput/AbilityCastApiTests.cs |
Class <remarks> documents NEO-30 / Slice 3 ability_cast_denied contract; existing [Fact] methods already assert non-empty ReasonCode on every JSON deny. |
client/test/ability_cast_client_test.gd |
Comment tying client ability_cast_denied warning to server hook docs (pre-commit requires a staged test file with client/scripts edits). |
bruno/neon-sprawl-server/ability-cast/Post cast happy.bru |
Meta name touch so pre-commit stages Bruno with AbilityCastApi.cs edits. |
docs/manual-qa/NEO-30.md |
Human verification of hook tokens / HUD line after implementation. |
Open questions / risks
None.