From 4cfec3ac7f18af961cc1804d98f50b3058b6e043 Mon Sep 17 00:00:00 2001 From: VinPropane Date: Sun, 7 Jun 2026 15:01:34 -0400 Subject: [PATCH 1/3] NEO-123: Add implementation plan for quest chain capstone. Kickoff clarifications adopt docs-primary scope, Shift+Q catalog accept order, and Godot-restart idempotency per NEO-111 precedent. --- docs/plans/NEO-123-implementation-plan.md | 177 ++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 docs/plans/NEO-123-implementation-plan.md diff --git a/docs/plans/NEO-123-implementation-plan.md b/docs/plans/NEO-123-implementation-plan.md new file mode 100644 index 0000000..c8b0707 --- /dev/null +++ b/docs/plans/NEO-123-implementation-plan.md @@ -0,0 +1,177 @@ +# NEO-123 — Implementation plan + +## Story reference + +| Field | Value | +|--------|--------| +| **Key** | NEO-123 | +| **Title** | E7M1-12: Playable onboarding quest chain capstone (Godot) | +| **Linear** | https://linear.app/neon-sprawl/issue/NEO-123/e7m1-12-playable-onboarding-quest-chain-capstone-godot | +| **Module** | [E7.M1 — QuestStateMachine](../decomposition/modules/E7_M1_QuestStateMachine.md) · Epic 7 Slice 1 · backlog **E7M1-12** | +| **Branch** | `NEO-123-playable-onboarding-quest-chain-capstone` | +| **Client deps** | [NEO-122](https://linear.app/neon-sprawl/issue/NEO-122) quest progress + accept HUD (**Done**); [NEO-111](https://linear.app/neon-sprawl/issue/NEO-111) encounter clear capstone; [NEO-75](https://linear.app/neon-sprawl/issue/NEO-75) economy loop; [NEO-110](https://linear.app/neon-sprawl/issue/NEO-110) encounter HUD | +| **Server deps** | [NEO-112](https://linear.app/neon-sprawl/issue/NEO-112)–[NEO-121](https://linear.app/neon-sprawl/issue/NEO-121) quest spine (**landed on `main`**) | +| **Pattern** | Capstone integration — [NEO-111](NEO-111-implementation-plan.md) docs + manual QA primary; minimal gap-fill only if capstone QA fails on `main` | +| **Blocked by** | [NEO-122](https://linear.app/neon-sprawl/issue/NEO-122) (**Done**) | +| **Server counterpart** | NEO-112–NEO-121 server spine; Bruno-only verification is not prototype-complete per [full-stack epic decomposition](../../.cursor/rules/full-stack-epic-decomposition.md) | + +## Kickoff clarifications + +| Topic | Question | Agent recommendation | Answer | +|--------|----------|----------------------|--------| +| **Implementation scope** | Docs-only vs client code? | **Docs + manual QA primary**; fix integration gaps only if capstone QA fails on `main` — [NEO-111](NEO-111-implementation-plan.md) precedent. | **Adopted** — docs-primary | +| **Capstone intro accept order** | Scripted order for three onboarding intros? | **Shift+Q catalog order:** **Q** gather → **Shift+Q** combat → **Shift+Q** refine → **Shift+Q** operator chain — `prototype_quest_combat_intro` sorts before `prototype_quest_refine_intro` in defs order; matches `quest_hud_controller.gd` `_find_first_eligible_quest_id()`. | **Adopted** — Shift+Q catalog order | +| **Idempotency verification** | How to prove no duplicate quest completion on replay? | **Godot stop + F5 restart** (server still running) + retry **Q** / **Shift+Q** on completed quests; HUD statuses unchanged — mirrors [NEO-111](../manual-qa/NEO-111.md). | **Adopted** — Godot restart + duplicate accepts | +| **NEO-122 relationship** | Supersede component QA? | **NEO-123 supersedes as Slice 1 capstone**; keep [NEO-122](../manual-qa/NEO-122.md) as component-level regression (NEO-111 / NEO-110 pattern). | **Adopted** (default; no kickoff question) | + +**Additional defaults (no kickoff question — settled by backlog / precedent):** + +- **Session baseline:** fresh **server restart** before Godot **F5** — resets in-memory quest progress, inventory, encounter state, and resource-node depletion; zero Bruno/curl in main checklist. +- **Economy HUD:** toggle **on** for craft/inventory verification (NEO-75 / NEO-122 precedent). +- **Server changes:** none unless capstone QA exposes an authoritative bug (unlikely — covered by server quest tests). + +## Goal, scope, and out-of-scope + +**Goal:** Prove Epic 7 Slice 1 acceptance **in Godot**: complete all four prototype quests (three onboarding intros + one four-step operator chain) without Bruno; satisfies vision **quest loop** gate and [epic_07 Definition of Done](../decomposition/epics/epic_07_quest_faction.md#epic-7-definition-of-done). + +**In scope (from Linear + [E7M1-12](E7M1-prototype-backlog.md#e7m1-12--playable-onboarding-quest-chain-capstone-godot)):** + +- **`docs/manual-qa/NEO-123.md`**: numbered **single-session** capstone — fresh server restart; accept intros in **Shift+Q catalog order**; perform gather/craft/combat actions; verify **`prototype_quest_operator_chain`** completes when **`contract_handoff_token`** held; **idempotency** via Godot restart + duplicate accept keys. +- **`client/README.md`**: **End-to-end onboarding quest loop** section — integration flow table; cross-links NEO-112–NEO-122 and economy/combat capstones. +- **Module alignment** (on story completion): update [E7_M1](../decomposition/modules/E7_M1_QuestStateMachine.md) status, [documentation_and_implementation_alignment.md](../decomposition/modules/documentation_and_implementation_alignment.md) E7.M1 row, [module_dependency_register.md](../decomposition/modules/module_dependency_register.md) E7.M1 note, and [E7M1-prototype-backlog.md](E7M1-prototype-backlog.md) E7M1-12 checkboxes; mark Epic 7 Slice 1 client capstone complete. +- **Integration fixes only if capstone QA fails** on current `main` wiring (HUD refresh gap, eligible-accept edge case, chain step stall, idempotency breach, etc.). + +**Out of scope (from Linear + backlog):** + +- E7.M2 reward bundles; faction reputation; quest VFX art. +- Bruno-only verification as prototype-complete proof. +- New server HTTP routes or Godot HUD features beyond NEO-122. +- Eligible-quest picker redesign (catalog order is the documented contract for Slice 1). + +## Acceptance criteria checklist + +- [ ] Human completes **`docs/manual-qa/NEO-123.md`** with server + client. +- [ ] Epic 7 Slice 1 AC: 3 onboarding + 1 chain complete without duplicate completion on replay (idempotency steps pass). +- [ ] Re-read [epic_07 Definition of Done](../decomposition/epics/epic_07_quest_faction.md#epic-7-definition-of-done) for prototype minimums. + +## Technical approach + +### 1. Capstone manual QA script (`docs/manual-qa/NEO-123.md`) + +**Preconditions:** Stop any running server; start fresh (`cd server/NeonSprawl.Server && dotnet run`) so in-memory **`dev-local-1`** quest progress, inventory, encounter progress, NPC HP, and resource-node depletion reset. Godot **F5** with **no** prior curl/Bruno seeding. **`Economy HUD`** toggle **on**. + +**Quest catalog (frozen — `content/quests/prototype_quests.json`):** + +| Quest id | Display name | Prerequisites | Steps | +|----------|--------------|---------------|-------| +| `prototype_quest_gather_intro` | Intro: Salvage Run | none | gather **3** `scrap_metal_bulk` | +| `prototype_quest_combat_intro` | Intro: Clear the Pocket | none | `encounter_complete` **`prototype_combat_pocket`** | +| `prototype_quest_refine_intro` | Intro: Refine Stock | gather intro | craft **`refine_scrap_standard`** ×1 | +| `prototype_quest_operator_chain` | Operator Chain | all three intros | gather ×5 → refine ×1 → **`make_field_stim_mk0`** ×1 → **`inventory_has_item`** **`contract_handoff_token`** ×1 | + +**Accept key contract (NEO-122 / `quest_hud_controller.gd`):** + +| Key | Action | +|-----|--------| +| **Q** | Accept **`prototype_quest_gather_intro`** | +| **Shift+Q** | First catalog-order **`not_started`** quest with all **`prerequisiteQuestIds`** **`completed`** | + +**HTTP defs catalog order (ordinal `id`):** combat → gather → operator chain → refine. After gather intro completes, **Shift+Q** accepts **combat** (not refine). After combat completes, **Shift+Q** accepts **refine**. After all three intros complete, **Shift+Q** accepts **operator chain**. + +**Expected quest HUD progression (`QuestProgressLabel`):** + +| Phase | Action | Expected HUD lines (high level) | +|-------|--------|--------------------------------| +| Boot | Godot **F5** | All four quests **`not started`** | +| Gather intro | **Q** → gather **3** scrap (**R** at nodes) | Salvage Run **`active`** → counter → **`completed`** | +| Combat intro | **Shift+Q** → defeat ×3 NPCs (**Tab** + **1**) | Clear the Pocket **`active`** → **`completed`**; encounter **`completed (3/3)`**; loot includes **`contract_handoff_token`** | +| Refine intro | **Shift+Q** → craft **`refine_scrap_standard`** | Refine Stock **`active`** → **`completed`** | +| Operator chain | **Shift+Q** → chain steps | Operator Chain **`active step 1…4`** → **`completed`** when token held | +| Idempotency | Godot restart + **Q** / **Shift+Q** | All four remain **`completed`**; accept deny / no eligible quest | + +**Material / action notes for script author:** + +- Combat loot grants **`scrap_metal_bulk` ×10** + **`contract_handoff_token` ×1** (NEO-111) — satisfies chain terminal **`inventory_has_item`** once combat intro completes (token persists for chain step 4). +- Chain step 1 requires **5** successful gathers **while chain step 1 is active** (objective counter; prior bag scrap does not substitute). Use [NEO-75](../manual-qa/NEO-75.md) anchor table (**alpha** +1, **beta** +2, **gamma** +3, **delta** +5). +- Chain step 3 **`make_field_stim_mk0`** needs **2** `refined_plate_stock` + **1** scrap — plan extra **`refine_scrap_standard`** crafts after combat loot if bag is short on plates. +- Defeat order for combat pocket is **flexible** (NEO-111); script asserts **0/3 → completed (3/3)** only. + +**Main checklist spine (to expand in `docs/manual-qa/NEO-123.md`):** + +1. Start server + Godot **F5**; confirm four quests **`not started`**. +2. **Q** accept gather intro; gather until **`Intro: Salvage Run: completed`**. +3. **Shift+Q** accept combat intro; defeat three prototype NPCs; confirm encounter + combat intro **`completed`** and bag contains **`contract_handoff_token`**. +4. **Shift+Q** accept refine intro; craft **`refine_scrap_standard`**; confirm refine intro **`completed`**. +5. **Shift+Q** accept operator chain; complete steps 1–4 (gather ×5, refine, stim craft, token check); confirm **`Operator Chain: completed`**. +6. **Record** final quest HUD snapshot (all four **`completed`**). +7. **Idempotency — Godot restart:** stop Godot; **F5** again **without** stopping server. Quest HUD still shows all four **`completed`**. +8. **Idempotency — duplicate accepts:** **Q** on gather → **`denied — already_completed`**; **Shift+Q** → **`no eligible quest`** (or deny on ineligible pick); HUD unchanged from step 6. +9. Regression pointers: [NEO-122](../manual-qa/NEO-122.md) component HUD, [NEO-111](../manual-qa/NEO-111.md) encounter loot, [NEO-75](../manual-qa/NEO-75.md) economy craft. + +### 2. Client README (`client/README.md`) + +Add **End-to-end onboarding quest loop (NEO-123)** section after [Quest progress + accept HUD (NEO-122)](../../client/README.md#quest-progress--accept-hud-neo-122), mirroring NEO-111 / NEO-75 capstone sections: + +- One-line Epic 7 Slice 1 capstone goal. +- Flow table: fresh restart → **Q** gather → **Shift+Q** combat → **Shift+Q** refine → **Shift+Q** chain → four-step chain objectives → idempotency. +- Cross-links: NEO-112 catalog, NEO-118 wiring, NEO-119/120 HTTP, NEO-122 HUD, NEO-75 economy, NEO-111 combat token. +- Pointer to **`docs/manual-qa/NEO-123.md`**. + +### 3. Module / backlog alignment (on land) + +When capstone QA passes: + +- [E7M1-prototype-backlog.md](E7M1-prototype-backlog.md) — E7M1-12 AC checkboxes. +- [E7_M1_QuestStateMachine.md](../decomposition/modules/E7_M1_QuestStateMachine.md) — module status **Ready**; Slice 1 client capstone note. +- [documentation_and_implementation_alignment.md](../decomposition/modules/documentation_and_implementation_alignment.md) — E7.M1 row: NEO-123 landed; Epic 7 Slice 1 client capstone complete. +- [module_dependency_register.md](../decomposition/modules/module_dependency_register.md) — E7.M1 **Ready** when all stories landed. + +### 4. Integration fixes (conditional) + +Run capstone QA on `main` (or branch with NEO-122 merged). If any step fails: + +| Symptom | Likely fix surface | +|---------|-------------------| +| Quest HUD stale after gather/craft/defeat | `main.gd` refresh hook or `quest_hud_controller.gd` | +| Chain step counter stuck | Server wiring (unlikely) — file issue; client displays GET only | +| Token step not completing | Verify encounter loot + quest GET refresh on encounter **`completed`** (NEO-110 belt-and-suspenders) | +| Shift+Q picks unexpected quest | Document vs fix picker — **out of scope** unless script order is impossible | + +Document any fix in this plan’s **Implementation reconciliation** section and add regression note to manual QA. + +## Files to add + +| Path | Purpose | +|------|---------| +| `docs/plans/NEO-123-implementation-plan.md` | This plan. | +| `docs/manual-qa/NEO-123.md` | Single-session four-quest capstone checklist with idempotency + regression steps. | + +## Files to modify + +| Path | Rationale | +|------|-----------| +| `client/README.md` | **End-to-end onboarding quest loop (NEO-123)** section with flow table and cross-links. | +| `docs/manual-qa/NEO-122.md` | Cross-link to NEO-123 capstone; note intro accept order defers to capstone script. | +| `docs/plans/E7M1-prototype-backlog.md` | E7M1-12 AC checkboxes when capstone lands. | +| `docs/decomposition/modules/E7_M1_QuestStateMachine.md` | Module status **Ready** + capstone landed note on completion. | +| `docs/decomposition/modules/documentation_and_implementation_alignment.md` | E7.M1 row: NEO-123 landed; Slice 1 complete. | +| `docs/decomposition/modules/module_dependency_register.md` | E7.M1 **Ready** when capstone lands. | + +**Conditional (only if capstone QA fails):** `client/scripts/main.gd`, `client/scripts/quest_hud_controller.gd`, or related refresh wiring — minimal gap-fill; document paths in reconciliation. + +## Tests + +| Test file | What it covers | +|-----------|----------------| +| *(none planned)* | **Docs-primary scope** — server quest spine covered by **`QuestProgressApiTests`**, **`QuestAcceptApiTests`**, **`QuestObjectiveWiringTests`**, and content CI; client covered by NEO-122 GdUnit suites. Capstone proof is **`docs/manual-qa/NEO-123.md`** human QA. | + +If integration fixes land, add or extend GdUnit only when the fix introduces new client parse/refresh behavior worth locking (follow [testing-expectations.md](../../.cursor/rules/testing-expectations.md) AAA layout). + +## Open questions / risks + +| Item | Agent recommendation | Status | +|------|----------------------|--------| +| **NEO-122 manual QA step 6 (Shift+Q → refine)** | Capstone adopts **catalog order** (combat before refine); update NEO-122 cross-link note, not NEO-122 checklist retroactively unless user asks. | **adopted** | +| **Resource node depletion mid-session** | Script uses four anchors from NEO-75; fresh server gives enough total yield for intro + chain gathers. | **adopted** | +| **Chain step 4 before combat loot** | Script orders combat intro before chain accept; token in bag before chain step 4. | **adopted** | +| **Docs-only fails capstone** | Escalate to minimal client refresh fix in same story; record in reconciliation. | **deferred** | From ec71fba260954ee822cc9e7da68cc091a7a2388c Mon Sep 17 00:00:00 2001 From: VinPropane Date: Sun, 7 Jun 2026 15:03:29 -0400 Subject: [PATCH 2/3] NEO-123: Add capstone manual QA and onboarding quest loop docs. Ship four-quest Godot session script (Shift+Q catalog accept order, idempotency steps), client README capstone section, and align NEO-122 component QA with catalog-order picker behavior. --- client/README.md | 26 ++++ docs/manual-qa/NEO-122.md | 12 +- docs/manual-qa/NEO-123.md | 143 ++++++++++++++++++++++ docs/plans/E7M1-prototype-backlog.md | 2 + docs/plans/NEO-123-implementation-plan.md | 8 ++ 5 files changed, 185 insertions(+), 6 deletions(-) create mode 100644 docs/manual-qa/NEO-123.md diff --git a/client/README.md b/client/README.md index 77ee6e2..ff9fc75 100644 --- a/client/README.md +++ b/client/README.md @@ -239,6 +239,32 @@ Full checklist: [`docs/manual-qa/NEO-110.md`](../docs/manual-qa/NEO-110.md). Full checklist: [`docs/manual-qa/NEO-122.md`](../docs/manual-qa/NEO-122.md). +## End-to-end onboarding quest loop (NEO-123) + +Epic 7 Slice 1 capstone — complete all four prototype quests (three onboarding intros + operator chain) **in Godot** without Bruno. + +**Flow:** fresh server restart → **Q** gather intro → **Shift+Q** combat intro → **Shift+Q** refine intro → **Shift+Q** operator chain → four chain steps → Godot restart idempotency. + +| Step | Input / trigger | HUD / server outcome | +|------|-----------------|----------------------| +| Boot | Godot **F5** + fresh server | Four quests **`not started`**; empty bag | +| Gather intro | **Q** + **R** at nodes (×3 scrap) | Salvage Run **`active`** → **`completed`** | +| Combat intro | **Shift+Q** + defeat ×3 NPCs | Clear the Pocket **`completed`**; encounter **`completed (3/3)`**; **`contract_handoff_token`** in bag | +| Refine intro | **Shift+Q** + craft **`refine_scrap_standard`** | Refine Stock **`completed`** | +| Operator chain | **Shift+Q** + chain objectives | Operator Chain **`active step 1…4`** → **`completed`** when token held | +| Idempotency | Stop Godot + **F5** (server still running) | All four quests still **`completed`** | +| Duplicate accept | **Q** / **Shift+Q** on finished quests | **`already_completed`** / **`no eligible quest`**; HUD unchanged | + +**Accept order note:** **Shift+Q** uses quest-definitions **catalog order** (ordinal `id`). After gather intro completes, combat intro is offered before refine intro — see [`docs/manual-qa/NEO-123.md`](../docs/manual-qa/NEO-123.md). + +**Cross-links:** [NEO-112](../docs/plans/NEO-112-implementation-plan.md) catalog · [NEO-118](../docs/plans/NEO-118-implementation-plan.md) objective wiring · [NEO-119](../docs/plans/NEO-119-implementation-plan.md) quest-progress GET · [NEO-120](../docs/plans/NEO-120-implementation-plan.md) accept POST · [NEO-122](../docs/manual-qa/NEO-122.md) HUD components · [NEO-75](../docs/manual-qa/NEO-75.md) economy craft · [NEO-111](../docs/manual-qa/NEO-111.md) combat token loot. + +**Scripts:** `quest_progress_client.gd`, `quest_definitions_client.gd`, `quest_hud_controller.gd`, `encounter_progress_client.gd`, `inventory_client.gd`, `craft_client.gd`, `ability_cast_client.gd` — wired from `main.gd`. + +**Preconditions:** **Server restart** before capstone run resets quest progress, inventory, encounter state, and resource nodes. + +Full capstone checklist: [`docs/manual-qa/NEO-123.md`](../docs/manual-qa/NEO-123.md). + ## End-to-end encounter clear loop (NEO-111) Epic 5 Slice 3 capstone — defeat all three prototype NPCs, receive loot + quest token **once**, verify inventory **in Godot** without Bruno. diff --git a/docs/manual-qa/NEO-122.md b/docs/manual-qa/NEO-122.md index 8cf94ba..e38e4b9 100644 --- a/docs/manual-qa/NEO-122.md +++ b/docs/manual-qa/NEO-122.md @@ -22,7 +22,7 @@ | **Q** accept gather | **`Intro: Salvage Run: active step 1`** | **`Quest accept: Intro: Salvage Run accepted`** | | Gather scrap (**R** on resource node ×3) | Gather objective counter increases (e.g. **`gather_intro_obj_scrap=3`**) | unchanged | | Gather quest completes | **`Intro: Salvage Run: completed`** | unchanged | -| **Shift+Q** accept refine (after gather complete) | **`Intro: Refine Stock: active step 1`** | **`Quest accept: Intro: Refine Stock accepted`** | +| **Shift+Q** after gather complete (catalog order) | **`Intro: Clear the Pocket: active`** — combat sorts before refine | **`Quest accept: Intro: Clear the Pocket accepted`** | | Craft **`refine_scrap_standard`** (Economy HUD) | Refine quest completes when recipe succeeds | unchanged | | Duplicate **Q** on gather | Gather row stays **`completed`** | **`Quest accept: denied — already_completed`** (or **`already_active`**) | @@ -33,9 +33,9 @@ 3. Press **Q**. Verify gather intro becomes **`active step 1`** and accept feedback shows success. 4. Gather scrap until gather quest completes (resource node **R**). Verify counter updates on **`QuestProgressLabel`** after each successful gather (may lag one GET). 5. Press **Shift+Q** before gather is complete — verify **`Quest accept: denied — prerequisite_incomplete`** for refine (or **`no eligible quest`** if refine is not yet eligible). -6. After gather completes, press **Shift+Q**. Verify refine quest becomes **`active`**. -7. Open **Economy HUD** recipe panel — **Refine Scrap (Standard)** is the **first** row (scroll starts at top). Craft when **≥5** scrap in bag. -8. Craft **`refine_scrap_standard`** with Economy HUD open. Verify refine quest **`completed`** after successful craft. +6. After gather completes, press **Shift+Q**. Verify **combat** intro becomes **`active`** (catalog order — combat before refine). Component refine/craft path: complete combat first, then repeat **Shift+Q** for refine; see [NEO-123 capstone](NEO-123.md) for full four-quest order. +7. Open **Economy HUD** recipe panel — **Refine Scrap (Standard)** is the **first** row (scroll starts at top). After combat intro is **`completed`** and refine intro is **`active`**, craft when **≥5** scrap in bag. +8. Craft **`refine_scrap_standard`** with Economy HUD open. Verify refine quest **`completed`** after successful craft (requires refine intro **`active`** from step 6 follow-up **Shift+Q**). 9. Press **Q** again on already-completed gather. Verify deny feedback on **`QuestAcceptFeedbackLabel`** without Bruno. 10. Optional: stop server while Godot running, press **Q** — verify **`Quests: error — …`** or **`Quest accept: failed — …`** visible on HUD. 11. Optional: block **`GET /game/world/quest-definitions`** only while progress GET succeeds — verify **`definitions error — …`** under **`QuestProgressLabel`** with raw quest ids as fallback. @@ -43,8 +43,8 @@ ## Notes -- Combat intro (**`prototype_quest_combat_intro`**) has no prerequisites — **Shift+Q** may offer it before refine if gather is still active; server deny is authoritative when prerequisites block accept. -- Full four-quest chain capstone: [NEO-123 manual QA](NEO-123.md). +- **Shift+Q** uses quest-definitions **catalog order** (ordinal `id`): after gather intro completes, **combat** intro is offered before **refine** intro. Server deny is authoritative when prerequisites block accept. +- Full four-quest chain capstone (supersedes partial intro path here): [NEO-123 manual QA](NEO-123.md). - Encounter progress HUD regression: [NEO-110 manual QA](NEO-110.md). ## Acceptance diff --git a/docs/manual-qa/NEO-123.md b/docs/manual-qa/NEO-123.md new file mode 100644 index 0000000..c784910 --- /dev/null +++ b/docs/manual-qa/NEO-123.md @@ -0,0 +1,143 @@ +# NEO-123 — Manual QA checklist + +| Field | Value | +|-------|-------| +| Key | NEO-123 | +| Title | E7M1-12: Playable onboarding quest chain capstone (Godot) | +| Linear | https://linear.app/neon-sprawl/issue/NEO-123/e7m1-12-playable-onboarding-quest-chain-capstone-godot | +| Plan | `docs/plans/NEO-123-implementation-plan.md` | +| Branch | `NEO-123-playable-onboarding-quest-chain-capstone` | + +## Preconditions + +- **Fresh dev player:** stop any running server, then start a new instance so in-memory **`dev-local-1`** quest progress, inventory, encounter progress, NPC HP, and resource-node depletion reset. +- **No Bruno/curl** for this checklist — accept uses **Q** / **Shift+Q**; gameplay uses **R**, **Tab** + **1**, and Economy HUD **Craft** buttons only. +- NEO-112–NEO-122 quest spine and NEO-75/NEO-111 economy/combat capstones landed on `main`. +- **`Economy HUD`** toggle **on** for craft and inventory verification. + +## Quest catalog (frozen) + +| Quest id | Display name | Prerequisites | Objective | +|----------|--------------|---------------|-----------| +| `prototype_quest_gather_intro` | Intro: Salvage Run | none | gather **3** `scrap_metal_bulk` | +| `prototype_quest_combat_intro` | Intro: Clear the Pocket | none | `encounter_complete` **`prototype_combat_pocket`** | +| `prototype_quest_refine_intro` | Intro: Refine Stock | gather intro | craft **`refine_scrap_standard`** ×1 | +| `prototype_quest_operator_chain` | Operator Chain | all three intros | gather ×5 → refine ×1 → **`make_field_stim_mk0`** ×1 → hold **`contract_handoff_token`** ×1 | + +## Accept key contract + +| Key | Action | +|-----|--------| +| **Q** | Accept **`prototype_quest_gather_intro`** | +| **Shift+Q** | First catalog-order **`not_started`** quest with all **`prerequisiteQuestIds`** **`completed`** | + +**Catalog order (ordinal `id`):** combat → gather → operator chain → refine. After gather intro completes, **Shift+Q** accepts **combat** (not refine). After combat completes, **Shift+Q** accepts **refine**. After all three intros complete, **Shift+Q** accepts **operator chain**. + +## Resource node anchors (gather) + +| Node id | Anchor | Yield per **R** | +|---------|--------|-----------------| +| `prototype_resource_node_alpha` | **(12, −6)** | +1 scrap | +| `prototype_subsurface_vein_beta` | **(18, −6)** | +2 scrap | +| `prototype_bio_mat_gamma` | **(12, 0)** | +3 scrap | +| `prototype_urban_bulk_delta` | **(18, 0)** | +5 scrap | + +Nodes allow multiple gathers (`maxGathers` **10** each). Quest gather counters credit **scrap quantity granted**, not gather event count. + +## Combat archetypes (defeat order flexible) + +| Archetype | Instance id | Marker | Pulses to defeat | +|-----------|-------------|--------|------------------| +| Melee | `prototype_npc_melee` | orange west **`(-3, -3)`** | 4 | +| Ranged | `prototype_npc_ranged` | purple SE **`(3, 3)`** | 4 | +| Elite | `prototype_npc_elite` | gold origin **`(0, 0)`** | 8 | + +Player casts **`prototype_pulse`** (**25** damage, ~**3 s** cooldown). + +## Expected quest HUD progression + +| Phase | `QuestProgressLabel` (high level) | `QuestAcceptFeedbackLabel` | +|-------|-----------------------------------|----------------------------| +| Boot | All four **`not started`** | **`Quest accept: — (Q gather / Shift+Q next)`** | +| Gather intro | Salvage Run **`active step 1`** → **`completed`** | **`accepted`** on **Q** | +| Combat intro | Clear the Pocket **`active`** → **`completed`** | **`accepted`** on **Shift+Q** | +| Refine intro | Refine Stock **`active`** → **`completed`** | **`accepted`** on **Shift+Q** | +| Operator chain | Operator Chain **`active step 1…4`** → **`completed`** | **`accepted`** on **Shift+Q** | +| Idempotency | All four still **`completed`** | **Q** deny / **Shift+Q** no eligible | + +## Material math (suggested path) + +| Phase | Actions | Bag after (approx.) | +|-------|---------|---------------------| +| Gather intro | **Q**; **R** at **gamma** once (+3 scrap) | 3 scrap | +| Combat intro | **Shift+Q**; defeat ×3 NPCs | 13 scrap, 1 token (+10 scrap loot) | +| Refine intro | **Shift+Q**; craft **`refine_scrap_standard`** | 8 scrap, 1 plate, 1 token | +| Chain step 1 | **Shift+Q**; **R** at **delta** once (+5 scrap) | 13 scrap; counter **5/5** | +| Chain step 2 | Craft **`refine_scrap_standard`** | 8 scrap, 2 plates, 1 token | +| Chain step 3 | Craft **`make_field_stim_mk0`** | 7 scrap, 0 plates, 1 stim, 1 token | +| Chain step 4 | Token already held from combat loot | Operator Chain **`completed`** | + +Adjust gathers/crafts if bag counts differ; counters and craft denies are authoritative. + +## Checklist + +### Boot + +1. Start server: `cd server/NeonSprawl.Server && dotnet run`. +2. Run Godot main scene (**F5**). Confirm **`QuestProgressLabel`** lists four **`not started`** quests and **`QuestAcceptFeedbackLabel`** shows the idle hint (in **`HudRootScroll`**). **`Economy HUD`** on; economy panel pinned bottom-left. + +### Intro: Salvage Run (gather) + +3. Press **Q**. Verify **`Intro: Salvage Run: active step 1`** and accept success feedback. +4. Walk to **gamma** **(12, 0)**; press **R** once. Verify counter **`chain_obj_gather`** is **not** present yet; gather intro counter increases (e.g. **`gather_intro_obj_scrap=3`**). +5. Verify **`Intro: Salvage Run: completed`**. + +### Intro: Clear the Pocket (combat) + +6. Press **Shift+Q**. Verify **`Intro: Clear the Pocket: active`** (combat intro — catalog order picks combat before refine). +7. Defeat all three prototype NPCs (**Tab** + **1**, any order). Verify **`EncounterProgressLabel`** **`completed (3/3)`** and **`EncounterCompleteLabel`** lists **`scrap_metal_bulk ×10`** + **`contract_handoff_token ×1`**. +8. Verify **`Intro: Clear the Pocket: completed`** and **`InventoryLabel`** shows **`contract_handoff_token`** (**1**). + +### Intro: Refine Stock (craft) + +9. Press **Shift+Q**. Verify **`Intro: Refine Stock: active step 1`**. +10. In Economy HUD, **Craft** **`refine_scrap_standard`** when **≥5** scrap in bag. Verify **`Intro: Refine Stock: completed`**. + +### Operator Chain (four steps) + +11. Press **Shift+Q**. Verify **`Operator Chain: active step 1`**. +12. **Chain step 1 — gather ×5:** press **R** at resource nodes until step advances (suggested: **delta** once for +5 scrap). Verify **`active step 2`** on **`QuestProgressLabel`**. +13. **Chain step 2 — refine:** craft **`refine_scrap_standard`**. Verify **`active step 3`**. +14. **Chain step 3 — stim:** craft **`make_field_stim_mk0`** (needs **2** plates + **1** scrap). Verify **`active step 4`**. +15. **Chain step 4 — token:** verify **`Operator Chain: completed`** without extra actions (token from step 8). + +### Capstone snapshot + +16. **Record** final **`QuestProgressLabel`**: all four quests **`completed`**. + +### Idempotency (no duplicate quest completion) + +17. **Godot restart:** stop Godot (**Shift+F5**); **F5** again **without** stopping the server. Verify all four quests still **`completed`**. +18. Press **Q** on gather intro. Verify **`Quest accept: denied — already_completed`** (or **`already_active`**). +19. Press **Shift+Q**. Verify **`Quest accept: no eligible quest`** (or equivalent deny). Quest HUD **unchanged** from step 16. + +### Regression + +20. Component quest HUD: [NEO-122 manual QA](NEO-122.md). +21. Encounter loot + token: [NEO-111 manual QA](NEO-111.md). +22. Economy craft panel: [NEO-75 manual QA](NEO-75.md). + +## Notes + +- **Shift+Q catalog order** is intentional for Slice 1 — combat intro before refine intro after gather completes. Full capstone supersedes [NEO-122](NEO-122.md) partial intro path. +- Combat defeat order is flexible; only **0/3 → completed (3/3)** is asserted. +- Chain terminal step is **`inventory_has_item`** — no token consume in Slice 1. +- **`POST /game/__dev/combat-targets-fixture`** is **out of scope** — clears encounter progress unsuitable for idempotency ([server README — dev combat-target fixture](../../server/README.md#dev-combat-target-fixture-brunomanual-qa)). +- Epic 7 Slice 1 AC: 3 onboarding + 1 chain complete without duped completion ([epic_07 Definition of Done](../decomposition/epics/epic_07_quest_faction.md#epic-7-definition-of-done)). + +## Acceptance + +- [ ] Steps 1–19 completable in one session without Bruno/curl. +- [ ] All four prototype quests reach **`completed`**; operator chain finishes when **`contract_handoff_token`** held. +- [ ] Godot restart + duplicate **Q**/**Shift+Q** leave quest statuses unchanged (no duplicate completion). +- [ ] Epic 7 Slice 1 AC satisfied in Godot. diff --git a/docs/plans/E7M1-prototype-backlog.md b/docs/plans/E7M1-prototype-backlog.md index a147e83..c4424fc 100644 --- a/docs/plans/E7M1-prototype-backlog.md +++ b/docs/plans/E7M1-prototype-backlog.md @@ -372,6 +372,8 @@ Working backlog for **Epic 7 — Slice 1** ([quest core and persistence](../deco - [ ] Epic 7 Slice 1 AC: 3 onboarding + 1 chain complete without duplicate completion on replay. - [ ] Re-read [epic_07 Definition of Done](../decomposition/epics/epic_07_quest_faction.md#definition-of-done) for prototype minimums. +**Landed (docs — NEO-123):** [`docs/manual-qa/NEO-123.md`](../manual-qa/NEO-123.md); [client README — End-to-end onboarding quest loop (NEO-123)](../../client/README.md#end-to-end-onboarding-quest-loop-neo-123); plan [NEO-123](../plans/NEO-123-implementation-plan.md). Human capstone QA + module **Ready** alignment pending. + **Client counterpart:** this story **is** the Slice 1 client capstone. --- diff --git a/docs/plans/NEO-123-implementation-plan.md b/docs/plans/NEO-123-implementation-plan.md index c8b0707..7f234be 100644 --- a/docs/plans/NEO-123-implementation-plan.md +++ b/docs/plans/NEO-123-implementation-plan.md @@ -54,6 +54,14 @@ - [ ] Epic 7 Slice 1 AC: 3 onboarding + 1 chain complete without duplicate completion on replay (idempotency steps pass). - [ ] Re-read [epic_07 Definition of Done](../decomposition/epics/epic_07_quest_faction.md#epic-7-definition-of-done) for prototype minimums. +## Implementation reconciliation (shipped — docs) + +- **`docs/manual-qa/NEO-123.md`** — single-session four-quest capstone with Shift+Q catalog accept order, material math, idempotency steps. +- **`client/README.md`** — **End-to-end onboarding quest loop (NEO-123)** section with flow table and cross-links. +- **`docs/manual-qa/NEO-122.md`** — catalog-order note + capstone cross-link; expected HUD table aligned with Shift+Q picker. +- **No integration code changes** — docs-primary scope pending human capstone QA on `main`. +- **Module alignment** (E7.M1 **Ready**, register row, backlog checkboxes): update after human QA passes steps 1–19. + ## Technical approach ### 1. Capstone manual QA script (`docs/manual-qa/NEO-123.md`) From f4e9f62533dc8c4d499af88f99a45b17c216caac Mon Sep 17 00:00:00 2001 From: VinPropane Date: Sun, 7 Jun 2026 15:07:59 -0400 Subject: [PATCH 3/3] NEO-123: Record capstone QA pass and mark E7.M1 Ready. Human QA passed; update acceptance checkboxes, module register, and alignment docs for Epic 7 Slice 1 client capstone completion. --- .../modules/E7_M1_QuestStateMachine.md | 2 +- .../documentation_and_implementation_alignment.md | 2 +- .../modules/module_dependency_register.md | 4 ++-- docs/manual-qa/NEO-123.md | 8 ++++---- docs/plans/E7M1-prototype-backlog.md | 8 ++++---- docs/plans/NEO-123-implementation-plan.md | 14 ++++++++------ 6 files changed, 20 insertions(+), 18 deletions(-) diff --git a/docs/decomposition/modules/E7_M1_QuestStateMachine.md b/docs/decomposition/modules/E7_M1_QuestStateMachine.md index e9057fc..c931843 100644 --- a/docs/decomposition/modules/E7_M1_QuestStateMachine.md +++ b/docs/decomposition/modules/E7_M1_QuestStateMachine.md @@ -7,7 +7,7 @@ | **Module ID** | E7.M1 | | **Epic** | [Epic 7 — Quest / Faction](../epics/epic_07_quest_faction.md) | | **Stage target** | Prototype | -| **Status** | Planned — Slice 1 backlog [E7M1-prototype-backlog.md](../../plans/E7M1-prototype-backlog.md): **E7M1-01** [NEO-112](https://linear.app/neon-sprawl/issue/NEO-112) catalog **landed** (schemas + CI); **E7M1-02** [NEO-113](https://linear.app/neon-sprawl/issue/NEO-113) server load **landed**; **E7M1-03** [NEO-114](https://linear.app/neon-sprawl/issue/NEO-114) registry **landed**; **E7M1-04** [NEO-115](https://linear.app/neon-sprawl/issue/NEO-115) HTTP read **landed**; **E7M1-05** [NEO-116](https://linear.app/neon-sprawl/issue/NEO-116) player quest state store **landed**; **E7M1-06** [NEO-117](https://linear.app/neon-sprawl/issue/NEO-117) **`QuestStateOperations`** **landed**; **E7M1-07** [NEO-118](https://linear.app/neon-sprawl/issue/NEO-118) **`QuestObjectiveWiring`** **landed**; **E7M1-08** [NEO-119](https://linear.app/neon-sprawl/issue/NEO-119) per-player GET **landed**; **E7M1-09** [NEO-120](https://linear.app/neon-sprawl/issue/NEO-120) accept POST **landed**; **E7M1-10** [NEO-121](https://linear.app/neon-sprawl/issue/NEO-121) telemetry hooks **landed**; **E7M1-11** [NEO-122](https://linear.app/neon-sprawl/issue/NEO-122) client quest HUD **landed**; capstone **E7M1-12** [NEO-123](https://linear.app/neon-sprawl/issue/NEO-123) | +| **Status** | **Ready** — Slice 1 backlog [E7M1-prototype-backlog.md](../../plans/E7M1-prototype-backlog.md) **E7M1-01** [NEO-112](https://linear.app/neon-sprawl/issue/NEO-112) → **E7M1-12** [NEO-123](https://linear.app/neon-sprawl/issue/NEO-123) **landed**. Client capstone [`NEO-123` manual QA](../../manual-qa/NEO-123.md); [client README — End-to-end onboarding quest loop (NEO-123)](../../../client/README.md#end-to-end-onboarding-quest-loop-neo-123). Epic 7 Slice 1 client capstone complete. | | **Linear** | Label **`E7.M1`** · [E7M1-prototype-backlog.md](../../plans/E7M1-prototype-backlog.md) | ## Purpose diff --git a/docs/decomposition/modules/documentation_and_implementation_alignment.md b/docs/decomposition/modules/documentation_and_implementation_alignment.md index 7f35890..775501f 100644 --- a/docs/decomposition/modules/documentation_and_implementation_alignment.md +++ b/docs/decomposition/modules/documentation_and_implementation_alignment.md @@ -59,7 +59,7 @@ Rows appear when work starts; default for unlisted modules is **Planned** / not | E5.M1 | Ready | **NEO-76 landed:** frozen prototype four-ability catalog in [`content/abilities/prototype_abilities.json`](../../../content/abilities/prototype_abilities.json); [`ability-def.schema.json`](../../../content/schemas/ability-def.schema.json); PR gate + [`validate_content.py`](../../../scripts/validate_content.py) E5M1 four-id gate ([NEO-76](../../plans/NEO-76-implementation-plan.md)). **NEO-77 landed:** fail-fast server load of `content/abilities/*_abilities.json` at startup — `server/NeonSprawl.Server/Game/Combat/` ([NEO-77](../../plans/NEO-77-implementation-plan.md)); [server README — Ability catalog](../../../server/README.md#ability-catalog-contentabilities-neo-77). **NEO-79 landed:** injectable **`IAbilityDefinitionRegistry`** + DI; hotbar/cast use **`TryNormalizeKnown`** ([NEO-79](../../plans/NEO-79-implementation-plan.md)); Bruno `bruno/neon-sprawl-server/hotbar-loadout/` + `ability-cast/` unknown-ability deny smokes. **NEO-78 landed:** **`GET /game/world/ability-definitions`** — `AbilityDefinitionsWorldApi` + DTOs in `Game/Combat/` ([NEO-78](../../plans/NEO-78-implementation-plan.md)); [server README — Ability definitions (NEO-78)](../../../server/README.md#ability-definitions-neo-78); Bruno `bruno/neon-sprawl-server/ability-definitions/`. **NEO-80 landed:** **`ICombatEntityHealthStore`** / **`InMemoryCombatEntityHealthStore`** — lazy init (Slice 1 flat 100 HP; **superseded by [NEO-91](../../plans/NEO-91-implementation-plan.md)** per-archetype catalog max HP + three NPC instance ids); DI via **`AddCombatEntityHealthStore()`** ([NEO-80](../../plans/NEO-80-implementation-plan.md)); [server README — Combat entity health (NEO-80, NEO-91)](../../../server/README.md#combat-entity-health-neo-80-neo-91). **NEO-81 landed:** **`CombatOperations.TryResolve`** + **`CombatResult`** + **`CombatReasonCodes`** — defeated pre-check deny, catalog damage ([NEO-81](../../plans/NEO-81-implementation-plan.md)); [server README — Combat engine (NEO-81)](../../../server/README.md#combat-engine-neo-81). **NEO-82 landed:** **`AbilityCastApi`** → **`CombatOperations.TryResolve`**; nested wire **`combatResolution`** on accept; per-ability catalog cooldown; **`target_defeated`** cast deny ([NEO-82](../../plans/NEO-82-implementation-plan.md)); [server README — Ability cast (NEO-82)](../../../server/README.md#ability-cast-neo-31-neo-82); Bruno `bruno/neon-sprawl-server/ability-cast/` defeat spine. **NEO-83 landed:** **`GET /game/world/combat-targets`** — `CombatTargetsWorldApi` + DTOs; authoritative HP snapshot from **`ICombatEntityHealthStore`** ([NEO-83](../../plans/NEO-83-implementation-plan.md)); [server README — Combat targets snapshot (NEO-83)](../../../server/README.md#combat-targets-snapshot-neo-83); Bruno `bruno/neon-sprawl-server/combat-targets/`. **NEO-44 landed:** **`CombatDefeatGigXpGrant`** on cast **`targetDefeated`** — **25** gig XP to **`breach`** via **`IPlayerGigProgressionStore`** (V007); **`GET …/gig-progression`** ([NEO-44](../../plans/NEO-44-implementation-plan.md), [`NEO-44` manual QA](../../manual-qa/NEO-44.md)); [server README — Gig progression (NEO-44)](../../../server/README.md#gig-progression-snapshot-neo-44); Bruno `bruno/neon-sprawl-server/gig-progression/`. **NEO-84 landed:** comment-only **`ability_used`** / **`enemy_defeat`** telemetry hook sites in **`CombatOperations.TryResolve`**; reserved **`encounter_start`** / **`player_death`** ([NEO-84](../../plans/NEO-84-implementation-plan.md)); [server README — Combat telemetry hooks (NEO-84)](../../../server/README.md#combat-telemetry-hooks-neo-84). **NEO-85 landed:** client combat HUD — **`ability_cast_client.gd`** parses **`combatResolution`**; **`combat_targets_client.gd`**, **`CastFeedbackLabel`** resolution copy, **`CombatTargetHpLabel`**; event-driven GET refresh ([NEO-85](../../plans/NEO-85-implementation-plan.md), [`NEO-85` manual QA](../../manual-qa/NEO-85.md)); `client/README.md` combat HUD section. **NEO-86 landed:** playable combat capstone — **`gig_progression_client.gd`**, **`GigXpLabel`**, defeat-triggered gig GET refresh; capstone manual QA [`NEO-86`](../../manual-qa/NEO-86.md); `client/README.md` end-to-end combat loop section ([NEO-86](../../plans/NEO-86-implementation-plan.md)). **Epic 5 Slice 1 client capstone complete.** **Backlog decomposed:** Epic 5 Slice 1 — **E5M1-01**–**E5M1-12** landed. **Precursor landed:** E1.M4 cast funnel (NEO-28/31/32). | [E5M1-prototype-backlog.md](../../plans/E5M1-prototype-backlog.md), [E5_M1](E5_M1_CombatRulesEngine.md), [NEO-77](../../plans/NEO-77-implementation-plan.md), [NEO-79](../../plans/NEO-79-implementation-plan.md), [NEO-78](../../plans/NEO-78-implementation-plan.md), [NEO-80](../../plans/NEO-80-implementation-plan.md), [NEO-81](../../plans/NEO-81-implementation-plan.md), [NEO-82](../../plans/NEO-82-implementation-plan.md), [NEO-83](../../plans/NEO-83-implementation-plan.md), [NEO-44](../../plans/NEO-44-implementation-plan.md), [NEO-84](../../plans/NEO-84-implementation-plan.md), [NEO-85](../../plans/NEO-85-implementation-plan.md), [NEO-86](../../plans/NEO-86-implementation-plan.md), [E1M4-prototype-backlog.md](../../plans/E1M4-prototype-backlog.md) | | E5.M2 | Ready | **NEO-87 landed:** frozen prototype three-behavior catalog in [`content/npc-behaviors/prototype_npc_behaviors.json`](../../../content/npc-behaviors/prototype_npc_behaviors.json); [`npc-behavior-def.schema.json`](../../../content/schemas/npc-behavior-def.schema.json); PR gate + [`validate_content.py`](../../../scripts/validate_content.py) E5M2 three-id gate ([NEO-87](../../plans/NEO-87-implementation-plan.md)). **NEO-88 landed:** fail-fast server load of `content/npc-behaviors/*_npc_behaviors.json` at startup — `server/NeonSprawl.Server/Game/Npc/` ([NEO-88](../../plans/NEO-88-implementation-plan.md)); [server README — NPC behavior catalog](../../../server/README.md#npc-behavior-catalog-contentnpc-behaviors-neo-88). **NEO-89 landed:** injectable **`INpcBehaviorDefinitionRegistry`** + DI; **`PrototypeNpcBehaviorRegistry`** id constants ([NEO-89](../../plans/NEO-89-implementation-plan.md)). **NEO-90 landed:** **`GET /game/world/npc-behavior-definitions`** — `NpcBehaviorDefinitionsWorldApi` + DTOs in `Game/Npc/` ([NEO-90](../../plans/NEO-90-implementation-plan.md)); [server README — NPC behavior definitions (NEO-90)](../../../server/README.md#npc-behavior-definitions-neo-90); Bruno `bruno/neon-sprawl-server/npc-behavior-definitions/`. **NEO-91 landed:** **`PrototypeNpcRegistry`** + combat-target migration — three NPC instance ids replace alpha/beta; per-archetype max HP from behavior catalog ([NEO-91](../../plans/NEO-91-implementation-plan.md)); [server README — Combat entity health (NEO-91)](../../../server/README.md#combat-entity-health-neo-80-neo-91). **NEO-92 landed:** **`IThreatStateStore`** + **`AggroOperations`** — first-hit acquire on damaging cast, leash clear on move/cast; cast/move/fixture hooks ([NEO-92](../../plans/NEO-92-implementation-plan.md)); [server README — Threat / aggro state (NEO-92)](../../../server/README.md#threat--aggro-state-neo-92). **NEO-93 landed:** **`INpcRuntimeStateStore`** + **`NpcRuntimeOperations.AdvanceAll`** — catalog-driven behavior state machine, lazy tick advance with delta cap; dev fixture reset ([NEO-93](../../plans/NEO-93-implementation-plan.md)); [server README — NPC runtime behavior state (NEO-93)](../../../server/README.md#npc-runtime-behavior-state-neo-93). **NEO-94 landed:** **`GET /game/world/npc-runtime-snapshot`** — `NpcRuntimeSnapshotWorldApi` + DTOs; lazy **`AdvanceAll`** on poll; nested **`activeTelegraph`** with server-computed **`windupRemainingSeconds`** ([NEO-94](../../plans/NEO-94-implementation-plan.md)); [server README — NPC runtime snapshot (NEO-94)](../../../server/README.md#npc-runtime-snapshot-neo-94); Bruno `bruno/neon-sprawl-server/npc-runtime-snapshot/`. **NEO-95 landed:** **`IPlayerCombatHealthStore`** + **`NpcAttackOperations.TryResolveTelegraphComplete`** — telegraph resolve via behavior **`attackAbilityId`** + ability **`maxRange`** / **`baseDamage`** ([NEO-95](../../plans/NEO-95-implementation-plan.md), [NEO-98](../../plans/NEO-98-implementation-plan.md)); [server README — Session player combat HP (NEO-95)](../../../server/README.md#session-player-combat-hp-neo-95); Bruno `bruno/neon-sprawl-server/combat-health/`. **NEO-96 landed:** comment-only **`telegraph_fired`** + **`npc_state_transition`** hook sites in **`NpcRuntimeOperations.AdvanceAll`** ([NEO-96](../../plans/NEO-96-implementation-plan.md)); [server README — NPC runtime telemetry hooks (NEO-96)](../../../server/README.md#npc-runtime-telemetry-hooks-neo-96). **NEO-97 landed:** client telegraph HUD — **`npc_runtime_client.gd`**, **`player_combat_health_client.gd`**, **`npc_runtime_hud_state.gd`**, **`TelegraphLabel`** / **`NpcStateLabel`** / **`PlayerCombatHpLabel`**; combat-active ~1 Hz poll ([NEO-97](../../plans/NEO-97-implementation-plan.md), [`NEO-97` manual QA](../../manual-qa/NEO-97.md)); [client README — NPC runtime + telegraph HUD (NEO-97)](../../../client/README.md#npc-runtime--telegraph-hud-neo-97). **NEO-98 landed:** playable NPC telegraph combat capstone — [`NEO-98` manual QA](../../manual-qa/NEO-98.md); `client/README.md` end-to-end NPC telegraph combat loop section ([NEO-98](../../plans/NEO-98-implementation-plan.md)). **NEO-98 server integration:** defeat clears aggro/runtime (**`TryStopOnTargetDefeat`**); telegraph damage range-gated via [`prototype_npc_abilities.json`](../../../content/abilities/prototype_npc_abilities.json) + behavior **`attackAbilityId`**. **Epic 5 Slice 2 client capstone complete.** **Backlog decomposed:** Epic 5 Slice 2 — [E5M2-prototype-backlog.md](../../plans/E5M2-prototype-backlog.md) **E5M2-01** [NEO-87](https://linear.app/neon-sprawl/issue/NEO-87) → **E5M2-12** [NEO-98](https://linear.app/neon-sprawl/issue/NEO-98) **landed**. Three archetypes (`prototype_melee_pressure`, `prototype_ranged_control`, `prototype_elite_mini_boss`); replaces alpha/beta dummies with **`prototype_npc_melee` / `ranged` / `elite`**. Owns **`ThreatState`**, **`TelegraphEvent`**, **`GET …/npc-runtime-snapshot`**, session **`IPlayerCombatHealthStore`**. Upstream **E5.M1 Ready**. | [E5M2-prototype-backlog.md](../../plans/E5M2-prototype-backlog.md), [E5_M2](E5_M2_NpcAiAndBehaviorProfiles.md), [NEO-87](../../plans/NEO-87-implementation-plan.md), [NEO-88](../../plans/NEO-88-implementation-plan.md), [NEO-89](../../plans/NEO-89-implementation-plan.md), [NEO-90](../../plans/NEO-90-implementation-plan.md), [NEO-91](../../plans/NEO-91-implementation-plan.md), [NEO-92](../../plans/NEO-92-implementation-plan.md), [NEO-93](../../plans/NEO-93-implementation-plan.md), [NEO-94](../../plans/NEO-94-implementation-plan.md), [NEO-95](../../plans/NEO-95-implementation-plan.md), [NEO-96](../../plans/NEO-96-implementation-plan.md), [NEO-97](../../plans/NEO-97-implementation-plan.md), [NEO-98](../../plans/NEO-98-implementation-plan.md), label **`E5.M2`** on NEO-87–NEO-98 | | E5.M3 | Ready | **E5M3-01 catalog landed ([NEO-100](https://linear.app/neon-sprawl/issue/NEO-100)):** encounter + reward-table schemas, `prototype_encounters.json`, `prototype_reward_tables.json`, CI gates. **E5M3-02 server load ([NEO-101](https://linear.app/neon-sprawl/issue/NEO-101)):** fail-fast startup loaders for encounter + reward-table catalogs (CI parity). **E5M3-03 registries ([NEO-102](https://linear.app/neon-sprawl/issue/NEO-102)):** `IEncounterDefinitionRegistry` + `IRewardTableDefinitionRegistry` + DI. **E5M3-04 HTTP read ([NEO-103](https://linear.app/neon-sprawl/issue/NEO-103)):** **`GET /game/world/encounter-definitions`** — `EncounterDefinitionsWorldApi` + nested **`rewardTable`** summary ([NEO-103](../../plans/NEO-103-implementation-plan.md)); [server README — Encounter definitions (NEO-103)](../../../server/README.md#encounter-definitions-neo-103); Bruno `bruno/neon-sprawl-server/encounter-definitions/`. **E5M3-05 stores ([NEO-104](https://linear.app/neon-sprawl/issue/NEO-104)):** **`IEncounterProgressStore`** + **`IEncounterCompletionStore`** + **`EncounterProgressOperations`** ([NEO-104](../../plans/NEO-104-implementation-plan.md)); [server README — Encounter progress (NEO-104)](../../../server/README.md#encounter-progress--completion-stores-neo-104). **E5M3-06 completion grants ([NEO-105](https://linear.app/neon-sprawl/issue/NEO-105)):** **`EncounterCompletionOperations`** + **`EncounterCompleteEvent`** result payload ([NEO-105](../../plans/NEO-105-implementation-plan.md)); [server README — Encounter completion (NEO-105)](../../../server/README.md#encounter-completion--inventory-grants-neo-105). **E5M3-07 combat wiring ([NEO-106](https://linear.app/neon-sprawl/issue/NEO-106)):** **`EncounterCombatWiring`** on **`AbilityCastApi`** ([NEO-106](../../plans/NEO-106-implementation-plan.md)); [server README — Encounter combat wiring (NEO-106)](../../../server/README.md#encounter-combat-wiring-neo-106). **E5M3-09 event record ([NEO-107](https://linear.app/neon-sprawl/issue/NEO-107)):** **`IEncounterCompleteEventStore`** + E7.M2 hook stub ([NEO-107](../../plans/NEO-107-implementation-plan.md)); [server README — Encounter complete event (NEO-107)](../../../server/README.md#encounter-complete-event-record-neo-107). **E5M3-08 per-player GET ([NEO-108](https://linear.app/neon-sprawl/issue/NEO-108)):** **`GET /game/players/{id}/encounter-progress`** — `EncounterProgressApi` + DTOs ([NEO-108](../../plans/NEO-108-implementation-plan.md)); [server README — Per-player encounter progress (NEO-108)](../../../server/README.md#per-player-encounter-progress-neo-108); Bruno `bruno/neon-sprawl-server/encounter-progress/`. **E5M3-10 telemetry ([NEO-109](https://linear.app/neon-sprawl/issue/NEO-109)):** comment-only **`encounter_start`**, **`encounter_complete`**, **`reward_attribution`**, **`encounter_complete_denied`** in **`EncounterProgressOperations`** / **`EncounterCompletionOperations`** ([NEO-109](../../plans/NEO-109-implementation-plan.md)); [server README — Encounter telemetry hooks (NEO-109)](../../../server/README.md#encounter-telemetry-hooks-neo-109). **E5M3-11 client HUD ([NEO-110](https://linear.app/neon-sprawl/issue/NEO-110)):** **`encounter_progress_client.gd`**, **`EncounterProgressLabel`** / **`EncounterCompleteLabel`**; boot + defeat-triggered GET; inventory refresh on **`completed`** ([NEO-110](../../plans/NEO-110-implementation-plan.md), [`NEO-110` manual QA](../../manual-qa/NEO-110.md)); [client README — Encounter progress + loot HUD (NEO-110)](../../../client/README.md#encounter-progress--loot-hud-neo-110). **E5M3-12 client capstone ([NEO-111](https://linear.app/neon-sprawl/issue/NEO-111)):** playable encounter clear loop — [`NEO-111` manual QA](../../manual-qa/NEO-111.md); [client README — End-to-end encounter clear loop (NEO-111)](../../../client/README.md#end-to-end-encounter-clear-loop-neo-111); plan [NEO-111](../../plans/NEO-111-implementation-plan.md). **Epic 5 Slice 3 client capstone complete.** Epic 5 Slice 3 backlog [E5M3-prototype-backlog.md](../../plans/E5M3-prototype-backlog.md) **E5M3-01** [NEO-100](https://linear.app/neon-sprawl/issue/NEO-100) → **E5M3-12** [NEO-111](https://linear.app/neon-sprawl/issue/NEO-111) **landed**. Prototype spine: **`prototype_combat_pocket`** → **`prototype_combat_pocket_clear`**; idempotent completion; per-defeat gig XP unchanged ([NEO-44](../../plans/NEO-44-implementation-plan.md)). Upstream **E5.M2 Ready**, **E3.M3** inventory landed. | [NEO-111 plan](../../plans/NEO-111-implementation-plan.md), [NEO-110 plan](../../plans/NEO-110-implementation-plan.md), [NEO-109 plan](../../plans/NEO-109-implementation-plan.md), [NEO-108 plan](../../plans/NEO-108-implementation-plan.md), [NEO-107 plan](../../plans/NEO-107-implementation-plan.md), [NEO-106 plan](../../plans/NEO-106-implementation-plan.md), [NEO-105 plan](../../plans/NEO-105-implementation-plan.md), [NEO-104 plan](../../plans/NEO-104-implementation-plan.md), [NEO-103 plan](../../plans/NEO-103-implementation-plan.md), [NEO-102 plan](../../plans/NEO-102-implementation-plan.md), [E5_M3](E5_M3_EncounterAndRewardTables.md), label **`E5.M3`** on NEO-100–NEO-111 | -| E7.M1 | Planned | **E7M1-01 catalog landed ([NEO-112](https://linear.app/neon-sprawl/issue/NEO-112)):** quest schemas, `prototype_quests.json`, CI gates (four frozen quest ids, objective cross-refs, acyclic prerequisites, chain terminal token). **E7M1-02 server load ([NEO-113](https://linear.app/neon-sprawl/issue/NEO-113)):** fail-fast startup load of `content/quests/*_quests.json` — `server/NeonSprawl.Server/Game/Quests/` ([NEO-113](../../plans/NEO-113-implementation-plan.md)); [server README — Quest catalog](../../../server/README.md#quest-catalog-contentquests-neo-113). **E7M1-03 registry ([NEO-114](https://linear.app/neon-sprawl/issue/NEO-114)):** **`IQuestDefinitionRegistry`** + DI ([NEO-114](../../plans/NEO-114-implementation-plan.md)). **E7M1-04 HTTP read ([NEO-115](https://linear.app/neon-sprawl/issue/NEO-115)):** **`GET /game/world/quest-definitions`** — `QuestDefinitionsWorldApi` + DTOs ([NEO-115](../../plans/NEO-115-implementation-plan.md)); [server README — Quest definitions (NEO-115)](../../../server/README.md#quest-definitions-neo-115); Bruno `bruno/neon-sprawl-server/quest-definitions/`. **E7M1-05 store ([NEO-116](https://linear.app/neon-sprawl/issue/NEO-116)):** **`IPlayerQuestStateStore`** + in-memory/Postgres persistence ([NEO-116](../../plans/NEO-116-implementation-plan.md)); [server README — Quest progress store (NEO-116)](../../../server/README.md#quest-progress-store-neo-116). **E7M1-06 operations ([NEO-117](https://linear.app/neon-sprawl/issue/NEO-117)):** **`QuestStateOperations`** + reason codes ([NEO-117](../../plans/NEO-117-implementation-plan.md)); [server README — Quest state operations (NEO-117)](../../../server/README.md#quest-state-operations-neo-117). **E7M1-07 objective wiring ([NEO-118](https://linear.app/neon-sprawl/issue/NEO-118)):** **`QuestObjectiveWiring`** on gather/craft/encounter + **`inventory_has_item`** snapshot passes ([NEO-118](../../plans/NEO-118-implementation-plan.md)); [server README — Quest objective wiring (NEO-118)](../../../server/README.md#quest-objective-wiring-neo-118). **E7M1-08 per-player GET ([NEO-119](https://linear.app/neon-sprawl/issue/NEO-119)):** **`GET /game/players/{id}/quest-progress`** — `QuestProgressApi` + DTOs; GET-side inventory refresh ([NEO-119](../../plans/NEO-119-implementation-plan.md)); [server README — Per-player quest progress (NEO-119)](../../../server/README.md#per-player-quest-progress-neo-119); Bruno `bruno/neon-sprawl-server/quest-progress/`. **E7M1-09 accept POST ([NEO-120](https://linear.app/neon-sprawl/issue/NEO-120)):** **`POST /game/players/{id}/quests/{questId}/accept`** — `QuestAcceptApi` + DTOs; **`QuestStateOperations.TryAccept`** ([NEO-120](../../plans/NEO-120-implementation-plan.md)); [server README — Quest accept POST (NEO-120)](../../../server/README.md#quest-accept-post-neo-120); Bruno accept spine in `bruno/neon-sprawl-server/quest-progress/`. **E7M1-10 telemetry ([NEO-121](https://linear.app/neon-sprawl/issue/NEO-121)):** comment-only **`quest_start`**, **`quest_step_complete`**, **`quest_complete`**, **`quest_accept_denied`** hook sites in **`QuestStateOperations`** ([NEO-121](../../plans/NEO-121-implementation-plan.md)); [server README — Quest telemetry hooks (NEO-121)](../../../server/README.md#quest-telemetry-hooks-neo-121). **E7M1-11 client HUD ([NEO-122](https://linear.app/neon-sprawl/issue/NEO-122)):** **`quest_progress_client.gd`**, **`quest_definitions_client.gd`**, **`QuestProgressLabel`** / **`QuestAcceptFeedbackLabel`**; boot + event-driven GET refresh; **Q** / **Shift+Q** accept ([NEO-122](../../plans/NEO-122-implementation-plan.md), [`NEO-122` manual QA](../../manual-qa/NEO-122.md)); [client README — Quest progress + accept HUD (NEO-122)](../../../client/README.md#quest-progress--accept-hud-neo-122). **Backlog decomposed (capstone E7M1-12):** Epic 7 Slice 1 — [E7M1-prototype-backlog.md](../../plans/E7M1-prototype-backlog.md) **E7M1-01** [NEO-112](https://linear.app/neon-sprawl/issue/NEO-112) → **E7M1-12** [NEO-123](https://linear.app/neon-sprawl/issue/NEO-123). Four frozen quests (3 onboarding + 1 gather→craft→combat chain); solo only; state-only completion in Slice 1 (rewards deferred to E7.M2). Client capstone **E7M1-12** [NEO-123](https://linear.app/neon-sprawl/issue/NEO-123). Upstream: E3.M1 gather **Ready**, E3.M2 craft **Ready**, E5.M3 encounter **`contract_handoff_token`** + **`EncounterCompleteEvent`** **Ready**. Register row stays **Planned** until client capstone **E7M1-12** [NEO-123](https://linear.app/neon-sprawl/issue/NEO-123). | [NEO-122 plan](../../plans/NEO-122-implementation-plan.md), [NEO-121 plan](../../plans/NEO-121-implementation-plan.md), [NEO-120 plan](../../plans/NEO-120-implementation-plan.md), [NEO-119 plan](../../plans/NEO-119-implementation-plan.md), [NEO-118 plan](../../plans/NEO-118-implementation-plan.md), [NEO-117 plan](../../plans/NEO-117-implementation-plan.md), [NEO-116 plan](../../plans/NEO-116-implementation-plan.md), [NEO-115 plan](../../plans/NEO-115-implementation-plan.md), [NEO-114 plan](../../plans/NEO-114-implementation-plan.md), [NEO-113 plan](../../plans/NEO-113-implementation-plan.md), [NEO-112 plan](../../plans/NEO-112-implementation-plan.md), [E7M1-prototype-backlog.md](../../plans/E7M1-prototype-backlog.md), [E7_M1](E7_M1_QuestStateMachine.md), label **`E7.M1`** on NEO-112–NEO-123 | +| E7.M1 | Ready | **E7M1-01 catalog landed ([NEO-112](https://linear.app/neon-sprawl/issue/NEO-112)):** quest schemas, `prototype_quests.json`, CI gates (four frozen quest ids, objective cross-refs, acyclic prerequisites, chain terminal token). **E7M1-02 server load ([NEO-113](https://linear.app/neon-sprawl/issue/NEO-113)):** fail-fast startup load of `content/quests/*_quests.json` — `server/NeonSprawl.Server/Game/Quests/` ([NEO-113](../../plans/NEO-113-implementation-plan.md)); [server README — Quest catalog](../../../server/README.md#quest-catalog-contentquests-neo-113). **E7M1-03 registry ([NEO-114](https://linear.app/neon-sprawl/issue/NEO-114)):** **`IQuestDefinitionRegistry`** + DI ([NEO-114](../../plans/NEO-114-implementation-plan.md)). **E7M1-04 HTTP read ([NEO-115](https://linear.app/neon-sprawl/issue/NEO-115)):** **`GET /game/world/quest-definitions`** — `QuestDefinitionsWorldApi` + DTOs ([NEO-115](../../plans/NEO-115-implementation-plan.md)); [server README — Quest definitions (NEO-115)](../../../server/README.md#quest-definitions-neo-115); Bruno `bruno/neon-sprawl-server/quest-definitions/`. **E7M1-05 store ([NEO-116](https://linear.app/neon-sprawl/issue/NEO-116)):** **`IPlayerQuestStateStore`** + in-memory/Postgres persistence ([NEO-116](../../plans/NEO-116-implementation-plan.md)); [server README — Quest progress store (NEO-116)](../../../server/README.md#quest-progress-store-neo-116). **E7M1-06 operations ([NEO-117](https://linear.app/neon-sprawl/issue/NEO-117)):** **`QuestStateOperations`** + reason codes ([NEO-117](../../plans/NEO-117-implementation-plan.md)); [server README — Quest state operations (NEO-117)](../../../server/README.md#quest-state-operations-neo-117). **E7M1-07 objective wiring ([NEO-118](https://linear.app/neon-sprawl/issue/NEO-118)):** **`QuestObjectiveWiring`** on gather/craft/encounter + **`inventory_has_item`** snapshot passes ([NEO-118](../../plans/NEO-118-implementation-plan.md)); [server README — Quest objective wiring (NEO-118)](../../../server/README.md#quest-objective-wiring-neo-118). **E7M1-08 per-player GET ([NEO-119](https://linear.app/neon-sprawl/issue/NEO-119)):** **`GET /game/players/{id}/quest-progress`** — `QuestProgressApi` + DTOs; GET-side inventory refresh ([NEO-119](../../plans/NEO-119-implementation-plan.md)); [server README — Per-player quest progress (NEO-119)](../../../server/README.md#per-player-quest-progress-neo-119); Bruno `bruno/neon-sprawl-server/quest-progress/`. **E7M1-09 accept POST ([NEO-120](https://linear.app/neon-sprawl/issue/NEO-120)):** **`POST /game/players/{id}/quests/{questId}/accept`** — `QuestAcceptApi` + DTOs; **`QuestStateOperations.TryAccept`** ([NEO-120](../../plans/NEO-120-implementation-plan.md)); [server README — Quest accept POST (NEO-120)](../../../server/README.md#quest-accept-post-neo-120); Bruno accept spine in `bruno/neon-sprawl-server/quest-progress/`. **E7M1-10 telemetry ([NEO-121](https://linear.app/neon-sprawl/issue/NEO-121)):** comment-only **`quest_start`**, **`quest_step_complete`**, **`quest_complete`**, **`quest_accept_denied`** hook sites in **`QuestStateOperations`** ([NEO-121](../../plans/NEO-121-implementation-plan.md)); [server README — Quest telemetry hooks (NEO-121)](../../../server/README.md#quest-telemetry-hooks-neo-121). **E7M1-11 client HUD ([NEO-122](https://linear.app/neon-sprawl/issue/NEO-122)):** **`quest_progress_client.gd`**, **`quest_definitions_client.gd`**, **`QuestProgressLabel`** / **`QuestAcceptFeedbackLabel`**; boot + event-driven GET refresh; **Q** / **Shift+Q** accept ([NEO-122](../../plans/NEO-122-implementation-plan.md), [`NEO-122` manual QA](../../manual-qa/NEO-122.md)); [client README — Quest progress + accept HUD (NEO-122)](../../../client/README.md#quest-progress--accept-hud-neo-122). **E7M1-12 client capstone ([NEO-123](https://linear.app/neon-sprawl/issue/NEO-123)):** playable four-quest onboarding chain — [`NEO-123` manual QA](../../manual-qa/NEO-123.md); [client README — End-to-end onboarding quest loop (NEO-123)](../../../client/README.md#end-to-end-onboarding-quest-loop-neo-123); plan [NEO-123](../../plans/NEO-123-implementation-plan.md). **Epic 7 Slice 1 client capstone complete.** Backlog **E7M1-01** [NEO-112](https://linear.app/neon-sprawl/issue/NEO-112) → **E7M1-12** [NEO-123](https://linear.app/neon-sprawl/issue/NEO-123) **landed**. Upstream: E3.M1 gather **Ready**, E3.M2 craft **Ready**, E5.M3 encounter **`contract_handoff_token`** + **`EncounterCompleteEvent`** **Ready**. | [NEO-123 plan](../../plans/NEO-123-implementation-plan.md), [NEO-122 plan](../../plans/NEO-122-implementation-plan.md), [NEO-121 plan](../../plans/NEO-121-implementation-plan.md), [NEO-120 plan](../../plans/NEO-120-implementation-plan.md), [NEO-119 plan](../../plans/NEO-119-implementation-plan.md), [NEO-118 plan](../../plans/NEO-118-implementation-plan.md), [NEO-117 plan](../../plans/NEO-117-implementation-plan.md), [NEO-116 plan](../../plans/NEO-116-implementation-plan.md), [NEO-115 plan](../../plans/NEO-115-implementation-plan.md), [NEO-114 plan](../../plans/NEO-114-implementation-plan.md), [NEO-113 plan](../../plans/NEO-113-implementation-plan.md), [NEO-112 plan](../../plans/NEO-112-implementation-plan.md), [E7M1-prototype-backlog.md](../../plans/E7M1-prototype-backlog.md), [E7_M1](E7_M1_QuestStateMachine.md), label **`E7.M1`** on NEO-112–NEO-123 | --- diff --git a/docs/decomposition/modules/module_dependency_register.md b/docs/decomposition/modules/module_dependency_register.md index f459329..a061534 100644 --- a/docs/decomposition/modules/module_dependency_register.md +++ b/docs/decomposition/modules/module_dependency_register.md @@ -107,9 +107,9 @@ Gameplay **content and curves** default to **boot load** with optional **dev-onl | Module ID | Module Name | Depends On | Contract Needed | Phase Required | Status | |---|---|---|---|---|---| -| E7.M1 | QuestStateMachine | E3.M2, E5.M1 | QuestDef, QuestStepState, QuestStateTransition | Prototype | Planned | +| E7.M1 | QuestStateMachine | E3.M2, E5.M1 | QuestDef, QuestStepState, QuestStateTransition | Prototype | Ready | -**E7.M1 note:** Epic 7 **Slice 1** backlog in Linear ([Epic 7 — Questing, Narrative, and Faction Reputation](https://linear.app/neon-sprawl/project/epic-7-questing-narrative-and-faction-reputation-a9416783ceee)): [NEO-112](https://linear.app/neon-sprawl/issue/NEO-112) → [NEO-123](https://linear.app/neon-sprawl/issue/NEO-123); label **`E7.M1`**. See [E7M1-prototype-backlog.md](../../plans/E7M1-prototype-backlog.md), [E7_M1_QuestStateMachine.md](E7_M1_QuestStateMachine.md). Upstream: E3.M1 gather **Ready**, E3.M2 craft **Ready**, E5.M3 encounter **Ready**. Client capstone **E7M1-12** [NEO-123](https://linear.app/neon-sprawl/issue/NEO-123). **E7M1-01 / NEO-112** catalog landed (schemas + CI); **E7M1-02 / NEO-113** server load landed; **E7M1-03 / NEO-114** registry landed ([NEO-114 plan](../../plans/NEO-114-implementation-plan.md)); **E7M1-04 / NEO-115** HTTP read landed ([NEO-115 plan](../../plans/NEO-115-implementation-plan.md)); **E7M1-05 / NEO-116** player quest state store landed ([NEO-116 plan](../../plans/NEO-116-implementation-plan.md)); **E7M1-06 / NEO-117** **`QuestStateOperations`** landed ([NEO-117 plan](../../plans/NEO-117-implementation-plan.md)); **E7M1-07 / NEO-118** **`QuestObjectiveWiring`** landed ([NEO-118 plan](../../plans/NEO-118-implementation-plan.md)); **E7M1-08 / NEO-119** per-player GET landed ([NEO-119 plan](../../plans/NEO-119-implementation-plan.md)); **E7M1-09 / NEO-120** accept POST landed ([NEO-120 plan](../../plans/NEO-120-implementation-plan.md)); **E7M1-10 / NEO-121** comment-only quest telemetry hook sites landed ([NEO-121 plan](../../plans/NEO-121-implementation-plan.md)); register row stays **Planned** until client capstone **E7M1-12** [NEO-123](https://linear.app/neon-sprawl/issue/NEO-123). +**E7.M1 note:** Epic 7 **Slice 1** backlog in Linear ([Epic 7 — Questing, Narrative, and Faction Reputation](https://linear.app/neon-sprawl/project/epic-7-questing-narrative-and-faction-reputation-a9416783ceee)): [NEO-112](https://linear.app/neon-sprawl/issue/NEO-112) → [NEO-123](https://linear.app/neon-sprawl/issue/NEO-123) **landed**; label **`E7.M1`**. See [E7M1-prototype-backlog.md](../../plans/E7M1-prototype-backlog.md), [E7_M1_QuestStateMachine.md](E7_M1_QuestStateMachine.md). Upstream: E3.M1 gather **Ready**, E3.M2 craft **Ready**, E5.M3 encounter **Ready**. **E7M1-12 / NEO-123** client capstone landed — [`NEO-123` manual QA](../../manual-qa/NEO-123.md), [client README — End-to-end onboarding quest loop (NEO-123)](../../../client/README.md#end-to-end-onboarding-quest-loop-neo-123), plan [NEO-123](../../plans/NEO-123-implementation-plan.md). Epic 7 Slice 1 client capstone complete. | E7.M2 | RewardAndUnlockRouter | E2.M2, E3.M3, E7.M1 | QuestRewardBundle, UnlockGrant, RewardDeliveryEvent | Prototype | Planned | | E7.M3 | FactionReputationLedger | E7.M1 | FactionStanding, ReputationDelta, FactionGateRule | Pre-production | Planned | | E7.M4 | ContractMissionGenerator | E4.M1, E5.M3, E7.M3 | ContractTemplate, ContractSeed, ContractOutcome | Pre-production | Planned | diff --git a/docs/manual-qa/NEO-123.md b/docs/manual-qa/NEO-123.md index c784910..b1db788 100644 --- a/docs/manual-qa/NEO-123.md +++ b/docs/manual-qa/NEO-123.md @@ -137,7 +137,7 @@ Adjust gathers/crafts if bag counts differ; counters and craft denies are author ## Acceptance -- [ ] Steps 1–19 completable in one session without Bruno/curl. -- [ ] All four prototype quests reach **`completed`**; operator chain finishes when **`contract_handoff_token`** held. -- [ ] Godot restart + duplicate **Q**/**Shift+Q** leave quest statuses unchanged (no duplicate completion). -- [ ] Epic 7 Slice 1 AC satisfied in Godot. +- [x] Steps 1–19 completable in one session without Bruno/curl. +- [x] All four prototype quests reach **`completed`**; operator chain finishes when **`contract_handoff_token`** held. +- [x] Godot restart + duplicate **Q**/**Shift+Q** leave quest statuses unchanged (no duplicate completion). +- [x] Epic 7 Slice 1 AC satisfied in Godot. diff --git a/docs/plans/E7M1-prototype-backlog.md b/docs/plans/E7M1-prototype-backlog.md index c4424fc..b5521fd 100644 --- a/docs/plans/E7M1-prototype-backlog.md +++ b/docs/plans/E7M1-prototype-backlog.md @@ -368,11 +368,11 @@ Working backlog for **Epic 7 — Slice 1** ([quest core and persistence](../deco **Acceptance criteria** -- [ ] Human completes **`docs/manual-qa/NEO-123.md`** with server + client. -- [ ] Epic 7 Slice 1 AC: 3 onboarding + 1 chain complete without duplicate completion on replay. -- [ ] Re-read [epic_07 Definition of Done](../decomposition/epics/epic_07_quest_faction.md#definition-of-done) for prototype minimums. +- [x] Human completes **`docs/manual-qa/NEO-123.md`** with server + client. +- [x] Epic 7 Slice 1 AC: 3 onboarding + 1 chain complete without duplicate completion on replay. +- [x] Re-read [epic_07 Definition of Done](../decomposition/epics/epic_07_quest_faction.md#definition-of-done) for prototype minimums. -**Landed (docs — NEO-123):** [`docs/manual-qa/NEO-123.md`](../manual-qa/NEO-123.md); [client README — End-to-end onboarding quest loop (NEO-123)](../../client/README.md#end-to-end-onboarding-quest-loop-neo-123); plan [NEO-123](../plans/NEO-123-implementation-plan.md). Human capstone QA + module **Ready** alignment pending. +**Landed (NEO-123):** [`docs/manual-qa/NEO-123.md`](../manual-qa/NEO-123.md); [client README — End-to-end onboarding quest loop (NEO-123)](../../client/README.md#end-to-end-onboarding-quest-loop-neo-123); plan [NEO-123](../plans/NEO-123-implementation-plan.md); E7.M1 **Ready**; Epic 7 Slice 1 client capstone complete. **Client counterpart:** this story **is** the Slice 1 client capstone. diff --git a/docs/plans/NEO-123-implementation-plan.md b/docs/plans/NEO-123-implementation-plan.md index 7f234be..00599ec 100644 --- a/docs/plans/NEO-123-implementation-plan.md +++ b/docs/plans/NEO-123-implementation-plan.md @@ -50,17 +50,19 @@ ## Acceptance criteria checklist -- [ ] Human completes **`docs/manual-qa/NEO-123.md`** with server + client. -- [ ] Epic 7 Slice 1 AC: 3 onboarding + 1 chain complete without duplicate completion on replay (idempotency steps pass). -- [ ] Re-read [epic_07 Definition of Done](../decomposition/epics/epic_07_quest_faction.md#epic-7-definition-of-done) for prototype minimums. +- [x] Human completes **`docs/manual-qa/NEO-123.md`** with server + client. +- [x] Epic 7 Slice 1 AC: 3 onboarding + 1 chain complete without duplicate completion on replay (idempotency steps pass). +- [x] Re-read [epic_07 Definition of Done](../decomposition/epics/epic_07_quest_faction.md#epic-7-definition-of-done) for prototype minimums. -## Implementation reconciliation (shipped — docs) +## Implementation reconciliation (shipped) + +**Manual QA:** [`docs/manual-qa/NEO-123.md`](../manual-qa/NEO-123.md) — passed (four-quest Godot capstone, Shift+Q catalog accept order, idempotency steps). - **`docs/manual-qa/NEO-123.md`** — single-session four-quest capstone with Shift+Q catalog accept order, material math, idempotency steps. - **`client/README.md`** — **End-to-end onboarding quest loop (NEO-123)** section with flow table and cross-links. - **`docs/manual-qa/NEO-122.md`** — catalog-order note + capstone cross-link; expected HUD table aligned with Shift+Q picker. -- **No integration code changes** — docs-primary scope pending human capstone QA on `main`. -- **Module alignment** (E7.M1 **Ready**, register row, backlog checkboxes): update after human QA passes steps 1–19. +- **`docs/plans/E7M1-prototype-backlog.md`**, **`E7_M1_QuestStateMachine.md`**, **`documentation_and_implementation_alignment.md`**, **`module_dependency_register.md`** — E7M1-12 landed; E7.M1 **Ready**; Epic 7 Slice 1 client capstone complete. +- **No integration code changes** — docs-primary scope; server quest spine verified by existing quest API / wiring tests. ## Technical approach