neon-sprawl/docs/manual-qa/NEO-143.md

119 lines
7.6 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.

# NEO-143 — Manual QA checklist
| Field | Value |
|-------|-------|
| Key | NEO-143 |
| Title | E7M3-11: Playable faction reputation + gate capstone (Godot) |
| Linear | https://linear.app/neon-sprawl/issue/NEO-143/e7m3-11-playable-faction-reputation-gate-capstone-godot |
| Plan | `docs/plans/NEO-143-implementation-plan.md` |
| Branch | `NEO-143-playable-faction-reputation-gate-capstone` |
## Preconditions
- **Fresh dev player:** stop any running server, then start a new instance so in-memory quest progress, faction standing, **`IRewardDeliveryStore`**, inventory, skill progression, 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-133NEO-142 faction spine and NEO-132 reward capstone landed on `main`.
- **`Economy HUD`** toggle **on** for inventory + skill verification.
## Faction + quest freeze (E7M3-01)
| Quest id | Display name | Rep grant on completion | Expected standing after |
|----------|--------------|-------------------------|-------------------------|
| `prototype_quest_operator_chain` | Operator Chain | **Grid Operators +15** (plus item/skill bundle — see NEO-132) | Grid Operators **15**, Rust Collective **0** |
| `prototype_quest_grid_contract` | Grid Contract | **Rust Collective +10** | Grid Operators **15**, Rust Collective **10** |
**Gate (component QA — not main capstone path):** accept **`prototype_quest_grid_contract`** at Grid Operators standing **0** with operator-chain prerequisite met ⇒ **`faction_gate_blocked`** with readable copy. Verified in [NEO-142](NEO-142.md) GdUnit (`client/test/faction_standing_hud_test.gd`) and optional dev fixture — organic Godot gameplay grants **+15** on operator-chain completion, so live capstone accept succeeds at standing **15**.
## Quest roster (five ids, catalog order)
| Quest id | Display name |
|----------|--------------|
| `prototype_quest_combat_intro` | Intro: Clear the Pocket |
| `prototype_quest_gather_intro` | Intro: Salvage Run |
| `prototype_quest_grid_contract` | Grid Contract |
| `prototype_quest_operator_chain` | Operator Chain |
| `prototype_quest_refine_intro` | Intro: Refine Stock |
**Shift+Q after operator chain:** only **`prototype_quest_grid_contract`** is eligible (**`not_started`**, prerequisite **`completed`**). Grid contract has one step — **`inventory_has_item`** **`survey_drone_kit` ×1** — satisfied from operator-chain reward; expect **`completed`** immediately on accept (no extra player action).
## Expected HUD progression
| Phase | `FactionStandingLabel` | `QuestProgressLabel` | `QuestRewardDeliveryLabel` |
|-------|------------------------|----------------------|----------------------------|
| Boot | Grid Operators **0**, Rust Collective **0** | Five quests **`not started`** | `Quest rewards:` / `—` |
| Operator chain **`completed`** | Grid Operators **15**, Rust Collective **0** | Four intros + operator chain **`completed`**; grid contract **`not started`** | Operator chain grants + **`Grid Operators +15 rep`** |
| Grid contract **`completed`** | Grid Operators **15**, Rust Collective **10** | All **five** **`completed`** | Grid Contract + **`Rust Collective +10 rep`** |
| Godot restart | Unchanged | All five still **`completed`** | `—` (transition-only) |
| Duplicate accepts | Unchanged | Unchanged | Unchanged |
## Checklist
Follow [NEO-132](NEO-132.md) steps **119** for the four-quest reward path (accept order, anchors, material math, reward + economy verification through operator chain). **Extend** with faction + fifth-quest steps below.
### Boot (faction baseline)
1. Start server: `cd server/NeonSprawl.Server && dotnet run`.
2. Run Godot main scene (**F5**). Confirm **`FactionStandingLabel`** shows **`Grid Operators: 0`**, **`Rust Collective: 0`**; **`QuestProgressLabel`** lists **five** quests all **`not started`**.
### Slice 2 reward path (inherit NEO-132)
3. Complete [NEO-132](NEO-132.md) steps **319** — four intros + operator chain with reward/economy checks at each completion.
### Faction standing after operator chain
4. Verify **`FactionStandingLabel`**: **`Grid Operators: 15`**, **`Rust Collective: 0`** — may lag reward label rep line by one faction-standing GET round-trip; confirm both within a moment after operator-chain completion.
5. Verify **`QuestRewardDeliveryLabel`** on operator-chain completion includes **`Grid Operators +15 rep`** (alongside item/skill lines).
6. Verify **`InventoryLabel`** still lists **`survey_drone_kit`**.
7. Verify **`QuestProgressLabel`**: grid contract **`not started`**; four prior quests **`completed`**.
### Grid contract accept + complete (faction-gated success path)
8. Press **Shift+Q** to accept **`prototype_quest_grid_contract`**. Verify **`QuestAcceptFeedbackLabel`** shows accept success (not **`faction_gate_blocked`**).
9. Verify **`Grid Contract: completed`** on **`QuestProgressLabel`** (instant complete — kit already held).
10. Verify **`QuestRewardDeliveryLabel`**: `Grid Contract` + **`Rust Collective +10 rep`**.
11. Verify **`FactionStandingLabel`**: **`Rust Collective: 10`** (Grid Operators still **15**).
### Capstone snapshot (record for idempotency)
12. **Record** final state:
- **`FactionStandingLabel`**: Grid Operators **15**, Rust Collective **10**
- **`QuestProgressLabel`**: all **five** quests **`completed`**
- **`SkillProgressionLabel`** / **`InventoryLabel`**: match NEO-132 step 20 totals
### Idempotency (no duplicate rep delivery)
13. **Godot restart:** stop Godot (**Shift+F5**); **F5** again **without** stopping the server.
14. Verify all five quests still **`completed`**; **`QuestRewardDeliveryLabel`** is **`—`** (transition-only).
15. Verify **`FactionStandingLabel`** counts **match step 12** exactly.
16. Press **Shift+Q**. Verify **`Quest accept: no eligible quest`** (or equivalent deny).
17. Verify faction standing and economy HUD counts **still match step 12** — no duplicate rep grants.
### Regression
18. Component faction HUD + gate deny: [NEO-142 manual QA](NEO-142.md) (GdUnit gate deny; optional dev fixture).
19. Slice 2 reward idempotency: [NEO-132 manual QA](NEO-132.md).
20. Slice 1 onboarding chain: [NEO-123 manual QA](NEO-123.md).
### Server AC (optional — not Godot gameplay)
```bash
cd /path/to/neon-sprawl && dotnet test NeonSprawl.sln \
--filter "FullyQualifiedName~ReputationOperationsTests|FullyQualifiedName~FactionGateOperationsTests|FullyQualifiedName~RewardRouterOperationsTests"
```
Expect all pass — auditable **`ReputationDelta`** apply + fail-closed gate evaluation. Content CI (`scripts/validate_content.py`) and server startup catalog cross-ref deny unknown faction ids at load (tamper fail-closed).
## Notes
- **Gate deny** is not exercised on the main capstone success path — see [NEO-142](NEO-142.md) step 6.
- Rep grants apply on quest **completion**, not accept; faction standing refreshes after in-session completion transition (NEO-142).
- Epic 7 Slice 3 AC: reputation deltas auditable; gates fail closed on tamper ([epic_07 Slice 3](../decomposition/epics/epic_07_quest_faction.md#slice-3---faction-ledger-pre-production)).
## Acceptance
- [ ] Steps 117 completable in one session without Bruno/curl.
- [ ] Operator chain grants Grid Operators **+15**; grid contract grants Rust Collective **+10** — visible on HUD.
- [ ] Faction-gated grid contract accept succeeds at standing **15** and completes with kit in bag.
- [ ] Godot restart + duplicate accepts leave faction standing unchanged (no double-claim).
- [ ] Epic 7 Slice 3 AC satisfied in Godot (gate deny regression via NEO-142; server AC via automated tests).