NEO-143: Add Slice 3 faction capstone manual QA and docs.
Ship NEO-143 capstone checklist extending NEO-132, client README end-to-end faction loop section, cross-links, and E7.M3 Ready alignment.pull/183/head
parent
0903bf00bd
commit
24a70d3566
|
|
@ -266,6 +266,30 @@ Full checklist: [`docs/manual-qa/NEO-131.md`](../docs/manual-qa/NEO-131.md).
|
||||||
|
|
||||||
Full checklist: [`docs/manual-qa/NEO-142.md`](../docs/manual-qa/NEO-142.md).
|
Full checklist: [`docs/manual-qa/NEO-142.md`](../docs/manual-qa/NEO-142.md).
|
||||||
|
|
||||||
|
## End-to-end faction reputation loop (NEO-143)
|
||||||
|
|
||||||
|
Epic 7 Slice 3 capstone — complete the NEO-132 four-quest reward path **in Godot**, earn Grid Operators rep from operator chain, accept faction-gated **`prototype_quest_grid_contract`** once, and verify Rust Collective rep on hand-in.
|
||||||
|
|
||||||
|
**Flow:** fresh server restart → NEO-132 four-quest path → standing **15** → **Shift+Q** grid contract accept/complete → Rust Collective **+10** → Godot restart idempotency.
|
||||||
|
|
||||||
|
| Step | Input / trigger | HUD / server outcome |
|
||||||
|
|------|-----------------|----------------------|
|
||||||
|
| Boot | Godot **F5** + fresh server | Five quests **`not started`**; faction standing **0** / **0** |
|
||||||
|
| Operator chain | **Shift+Q** + chain objectives (NEO-132) | Operator Chain **`completed`**; **`Grid Operators: 15`**; reward label includes **`Grid Operators +15 rep`**; bag has **`survey_drone_kit`** |
|
||||||
|
| Grid contract | **Shift+Q** after operator chain | Accept succeeds at standing **15**; quest **`completed`** immediately (kit held); **`Rust Collective: 10`**; reward label **`Rust Collective +10 rep`** |
|
||||||
|
| Idempotency | Stop Godot + **F5** (server still running) | Five quests still **`completed`**; faction standing unchanged; reward label **`—`** |
|
||||||
|
| Duplicate accept | **Shift+Q** on finished quests | **`no eligible quest`**; standing unchanged |
|
||||||
|
|
||||||
|
**Gate deny (component QA):** readable **`faction_gate_blocked`** copy on **`QuestAcceptFeedbackLabel`** is verified in [NEO-142](../docs/manual-qa/NEO-142.md) — not the main capstone success path (operator chain grants **+15** atomically on completion).
|
||||||
|
|
||||||
|
**Cross-links:** [NEO-133](../docs/plans/NEO-133-implementation-plan.md) content freeze · [NEO-136](../docs/plans/NEO-136-implementation-plan.md)–[NEO-138](../docs/plans/NEO-138-implementation-plan.md) rep apply · [NEO-139](../docs/plans/NEO-139-implementation-plan.md) standing GET · [NEO-140](../docs/plans/NEO-140-implementation-plan.md) gate/rep projections · [NEO-142](../docs/manual-qa/NEO-142.md) faction HUD · [NEO-132](../docs/manual-qa/NEO-132.md) reward capstone · [NEO-123](../docs/manual-qa/NEO-123.md) onboarding flow.
|
||||||
|
|
||||||
|
**Scripts:** `faction_standing_client.gd`, `quest_hud_controller.gd`, `quest_progress_client.gd`, `quest_definitions_client.gd` — wired from `main.gd`.
|
||||||
|
|
||||||
|
**Preconditions:** **Server restart** before capstone run resets quest progress, faction standing, reward delivery, inventory, and skill progression.
|
||||||
|
|
||||||
|
Full capstone checklist: [`docs/manual-qa/NEO-143.md`](../docs/manual-qa/NEO-143.md).
|
||||||
|
|
||||||
## End-to-end quest reward loop (NEO-132)
|
## End-to-end quest reward loop (NEO-132)
|
||||||
|
|
||||||
Epic 7 Slice 2 capstone — complete all four prototype quests **in Godot** and verify quest completion bundles (skill XP + item grants) apply **once** with idempotent replay.
|
Epic 7 Slice 2 capstone — complete all four prototype quests **in Godot** and verify quest completion bundles (skill XP + item grants) apply **once** with idempotent replay.
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
| **Module ID** | E7.M3 |
|
| **Module ID** | E7.M3 |
|
||||||
| **Epic** | [Epic 7 — Quest / Faction](../epics/epic_07_quest_faction.md) |
|
| **Epic** | [Epic 7 — Quest / Faction](../epics/epic_07_quest_faction.md) |
|
||||||
| **Stage target** | Pre-production |
|
| **Stage target** | Pre-production |
|
||||||
| **Status** | In Progress — **E7M3-01 catalog landed** ([NEO-133](https://linear.app/neon-sprawl/issue/NEO-133)); **E7M3-02 server faction catalog load landed** ([NEO-134](https://linear.app/neon-sprawl/issue/NEO-134)): fail-fast `content/factions/*_factions.json`, `IFactionDefinitionRegistry`, quest faction cross-ref + E7M3 bundle/grid gates; **E7M3-03 faction standing + reputation delta stores landed** ([NEO-135](https://linear.app/neon-sprawl/issue/NEO-135)): `IFactionStandingStore`, `IReputationDeltaStore`, in-memory + Postgres `V009`/`V010`; **E7M3-04 `ReputationOperations` landed** ([NEO-136](https://linear.app/neon-sprawl/issue/NEO-136)): auditable `TryApplyDelta` orchestration ([NEO-136 plan](../../plans/NEO-136-implementation-plan.md)); **E7M3-05 `FactionGateOperations` landed** ([NEO-137](https://linear.app/neon-sprawl/issue/NEO-137)): quest accept gate eval + `faction_gate_blocked` ([NEO-137 plan](../../plans/NEO-137-implementation-plan.md)); **E7M3-06 reward router rep grants landed** ([NEO-138](https://linear.app/neon-sprawl/issue/NEO-138)): `RewardRouterOperations` applies `reputationGrants` idempotently via `ReputationOperations` ([NEO-138 plan](../../plans/NEO-138-implementation-plan.md)); **E7M3-07 faction standing HTTP read landed** ([NEO-139](https://linear.app/neon-sprawl/issue/NEO-139)): `GET …/faction-standing` snapshot API + Bruno ([NEO-139 plan](../../plans/NEO-139-implementation-plan.md)); **E7M3-08 quest HTTP projections landed** ([NEO-140](https://linear.app/neon-sprawl/issue/NEO-140)): world GET `factionGateRules` + quest-progress `completionRewardSummary.reputationGrants` ([NEO-140 plan](../../plans/NEO-140-implementation-plan.md)); **E7M3-09 faction telemetry hooks landed** ([NEO-141](https://linear.app/neon-sprawl/issue/NEO-141)): comment-only **`reputation_delta`** + **`faction_gate_blocked`** in ops layers + README ([NEO-141 plan](../../plans/NEO-141-implementation-plan.md)); **E7M3-10 client faction HUD landed** ([NEO-142](https://linear.app/neon-sprawl/issue/NEO-142)): `faction_standing_client.gd`, `FactionStandingLabel`, readable `faction_gate_blocked` deny, `reputationGrants` reward lines ([NEO-142 plan](../../plans/NEO-142-implementation-plan.md)); [client README — Faction standing + gate feedback HUD (NEO-142)](../../../client/README.md#faction-standing--gate-feedback-hud-neo-142); [`NEO-142` manual QA](../../manual-qa/NEO-142.md). Slice 3 backlog **E7M3-11** [NEO-143](https://linear.app/neon-sprawl/issue/NEO-143). Upstream: E7.M1 **Ready**, E7.M2 **Ready**. |
|
| **Status** | Ready — **E7M3-01 catalog landed** ([NEO-133](https://linear.app/neon-sprawl/issue/NEO-133)); **E7M3-02 server faction catalog load landed** ([NEO-134](https://linear.app/neon-sprawl/issue/NEO-134)): fail-fast `content/factions/*_factions.json`, `IFactionDefinitionRegistry`, quest faction cross-ref + E7M3 bundle/grid gates; **E7M3-03 faction standing + reputation delta stores landed** ([NEO-135](https://linear.app/neon-sprawl/issue/NEO-135)): `IFactionStandingStore`, `IReputationDeltaStore`, in-memory + Postgres `V009`/`V010`; **E7M3-04 `ReputationOperations` landed** ([NEO-136](https://linear.app/neon-sprawl/issue/NEO-136)): auditable `TryApplyDelta` orchestration ([NEO-136 plan](../../plans/NEO-136-implementation-plan.md)); **E7M3-05 `FactionGateOperations` landed** ([NEO-137](https://linear.app/neon-sprawl/issue/NEO-137)): quest accept gate eval + `faction_gate_blocked` ([NEO-137 plan](../../plans/NEO-137-implementation-plan.md)); **E7M3-06 reward router rep grants landed** ([NEO-138](https://linear.app/neon-sprawl/issue/NEO-138)): `RewardRouterOperations` applies `reputationGrants` idempotently via `ReputationOperations` ([NEO-138 plan](../../plans/NEO-138-implementation-plan.md)); **E7M3-07 faction standing HTTP read landed** ([NEO-139](https://linear.app/neon-sprawl/issue/NEO-139)): `GET …/faction-standing` snapshot API + Bruno ([NEO-139 plan](../../plans/NEO-139-implementation-plan.md)); **E7M3-08 quest HTTP projections landed** ([NEO-140](https://linear.app/neon-sprawl/issue/NEO-140)): world GET `factionGateRules` + quest-progress `completionRewardSummary.reputationGrants` ([NEO-140 plan](../../plans/NEO-140-implementation-plan.md)); **E7M3-09 faction telemetry hooks landed** ([NEO-141](https://linear.app/neon-sprawl/issue/NEO-141)): comment-only **`reputation_delta`** + **`faction_gate_blocked`** in ops layers + README ([NEO-141 plan](../../plans/NEO-141-implementation-plan.md)); **E7M3-10 client faction HUD landed** ([NEO-142](https://linear.app/neon-sprawl/issue/NEO-142)): `faction_standing_client.gd`, `FactionStandingLabel`, readable `faction_gate_blocked` deny, `reputationGrants` reward lines ([NEO-142 plan](../../plans/NEO-142-implementation-plan.md)); [client README — Faction standing + gate feedback HUD (NEO-142)](../../../client/README.md#faction-standing--gate-feedback-hud-neo-142); [`NEO-142` manual QA](../../manual-qa/NEO-142.md). **E7M3-11 client capstone landed** ([NEO-143](https://linear.app/neon-sprawl/issue/NEO-143)): playable faction reputation + gate capstone — [`NEO-143` manual QA](../../manual-qa/NEO-143.md); [client README — End-to-end faction reputation loop (NEO-143)](../../../client/README.md#end-to-end-faction-reputation-loop-neo-143); plan [NEO-143](../../plans/NEO-143-implementation-plan.md). **Epic 7 Slice 3 client capstone complete.** Upstream: E7.M1 **Ready**, E7.M2 **Ready**. |
|
||||||
| **Linear** | Label **`E7.M3`** · [E7M3-pre-production-backlog.md](../../plans/E7M3-pre-production-backlog.md) |
|
| **Linear** | Label **`E7.M3`** · [E7M3-pre-production-backlog.md](../../plans/E7M3-pre-production-backlog.md) |
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -113,9 +113,9 @@ Gameplay **content and curves** default to **boot load** with optional **dev-onl
|
||||||
| E7.M2 | RewardAndUnlockRouter | E2.M2, E3.M3, E7.M1 | QuestRewardBundle, UnlockGrant, RewardDeliveryEvent | Prototype | Ready |
|
| E7.M2 | RewardAndUnlockRouter | E2.M2, E3.M3, E7.M1 | QuestRewardBundle, UnlockGrant, RewardDeliveryEvent | Prototype | Ready |
|
||||||
|
|
||||||
**E7.M2 note:** Epic 7 **Slice 2** 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-124](https://linear.app/neon-sprawl/issue/NEO-124) → [NEO-132](https://linear.app/neon-sprawl/issue/NEO-132) **landed**; label **`E7.M2`**. See [E7M2-prototype-backlog.md](../../plans/E7M2-prototype-backlog.md), [E7_M2_RewardAndUnlockRouter.md](E7_M2_RewardAndUnlockRouter.md). Upstream: E7.M1 **Ready**, E2.M2 grant stack ([NEO-43](https://linear.app/neon-sprawl/issue/NEO-43)), E3.M3 inventory **Ready**. **E7M2-09 / NEO-132** client capstone landed — [`NEO-132` manual QA](../../manual-qa/NEO-132.md), [client README — End-to-end quest reward loop (NEO-132)](../../../client/README.md#end-to-end-quest-reward-loop-neo-132), plan [NEO-132](../../plans/NEO-132-implementation-plan.md). Epic 7 Slice 2 client capstone complete.
|
**E7.M2 note:** Epic 7 **Slice 2** 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-124](https://linear.app/neon-sprawl/issue/NEO-124) → [NEO-132](https://linear.app/neon-sprawl/issue/NEO-132) **landed**; label **`E7.M2`**. See [E7M2-prototype-backlog.md](../../plans/E7M2-prototype-backlog.md), [E7_M2_RewardAndUnlockRouter.md](E7_M2_RewardAndUnlockRouter.md). Upstream: E7.M1 **Ready**, E2.M2 grant stack ([NEO-43](https://linear.app/neon-sprawl/issue/NEO-43)), E3.M3 inventory **Ready**. **E7M2-09 / NEO-132** client capstone landed — [`NEO-132` manual QA](../../manual-qa/NEO-132.md), [client README — End-to-end quest reward loop (NEO-132)](../../../client/README.md#end-to-end-quest-reward-loop-neo-132), plan [NEO-132](../../plans/NEO-132-implementation-plan.md). Epic 7 Slice 2 client capstone complete.
|
||||||
| E7.M3 | FactionReputationLedger | E7.M1, E7.M2 | FactionStanding, ReputationDelta, FactionGateRule | Pre-production | In Progress |
|
| E7.M3 | FactionReputationLedger | E7.M1, E7.M2 | FactionStanding, ReputationDelta, FactionGateRule | Pre-production | Ready |
|
||||||
|
|
||||||
**E7.M3 note:** Epic 7 **Slice 3** 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-133](https://linear.app/neon-sprawl/issue/NEO-133) → [NEO-143](https://linear.app/neon-sprawl/issue/NEO-143); label **`E7.M3`**. See [E7M3-pre-production-backlog.md](../../plans/E7M3-pre-production-backlog.md), [E7_M3_FactionReputationLedger.md](E7_M3_FactionReputationLedger.md). Upstream: E7.M1 **Ready**, E7.M2 **Ready**. Prototype spine: two frozen factions; operator chain grants **+15 Grid Operators**; **`prototype_quest_grid_contract`** gated at **minStanding 15**; rep grants via **`completionRewardBundle.reputationGrants`**; accept deny **`faction_gate_blocked`**. Client capstone **E7M3-11** [NEO-143](https://linear.app/neon-sprawl/issue/NEO-143).
|
**E7.M3 note:** Epic 7 **Slice 3** 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-133](https://linear.app/neon-sprawl/issue/NEO-133) → [NEO-143](https://linear.app/neon-sprawl/issue/NEO-143) **landed**; label **`E7.M3`**. See [E7M3-pre-production-backlog.md](../../plans/E7M3-pre-production-backlog.md), [E7_M3_FactionReputationLedger.md](E7_M3_FactionReputationLedger.md). Upstream: E7.M1 **Ready**, E7.M2 **Ready**. Prototype spine: two frozen factions; operator chain grants **+15 Grid Operators**; **`prototype_quest_grid_contract`** gated at **minStanding 15**; rep grants via **`completionRewardBundle.reputationGrants`**; accept deny **`faction_gate_blocked`**. **E7M3-11 / NEO-143** client capstone landed — [`NEO-143` manual QA](../../manual-qa/NEO-143.md), [client README — End-to-end faction reputation loop (NEO-143)](../../../client/README.md#end-to-end-faction-reputation-loop-neo-143), plan [NEO-143](../../plans/NEO-143-implementation-plan.md). Epic 7 Slice 3 client capstone complete.
|
||||||
| E7.M4 | ContractMissionGenerator | E4.M1, E5.M3, E7.M3 | ContractTemplate, ContractSeed, ContractOutcome | Pre-production | Planned |
|
| E7.M4 | ContractMissionGenerator | E4.M1, E5.M3, E7.M3 | ContractTemplate, ContractSeed, ContractOutcome | Pre-production | Planned |
|
||||||
|
|
||||||
### Epic 8 — Social / Guild
|
### Epic 8 — Social / Guild
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,7 @@ Follow [NEO-123](NEO-123.md) for accept order, anchors, material math, and quest
|
||||||
- Quest completion bundles are **idempotent** server-side (`{playerId}:quest_complete:{questId}`); Godot restart must not replay grant copy on **`QuestRewardDeliveryLabel`** (NEO-131 transition-only).
|
- Quest completion bundles are **idempotent** server-side (`{playerId}:quest_complete:{questId}`); Godot restart must not replay grant copy on **`QuestRewardDeliveryLabel`** (NEO-131 transition-only).
|
||||||
- Economy HUD auto-refreshes on quest completion transition (NEO-132); no manual **I** required for reward verification.
|
- Economy HUD auto-refreshes on quest completion transition (NEO-132); no manual **I** required for reward verification.
|
||||||
- Epic 7 Slice 2 AC: idempotent reward delivery; replays cannot double-claim ([epic_07 Slice 2](../decomposition/epics/epic_07_quest_faction.md#slice-2---reward-and-unlock-routing)).
|
- Epic 7 Slice 2 AC: idempotent reward delivery; replays cannot double-claim ([epic_07 Slice 2](../decomposition/epics/epic_07_quest_faction.md#slice-2---reward-and-unlock-routing)).
|
||||||
|
- **Faction standing + grid contract:** defer to [NEO-143](NEO-143.md) Slice 3 capstone (extends this checklist through **`prototype_quest_grid_contract`**).
|
||||||
|
|
||||||
## Acceptance
|
## Acceptance
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,4 +40,4 @@
|
||||||
- [NEO-122](NEO-122.md) — quest progress + accept HUD unchanged except new label below reward label.
|
- [NEO-122](NEO-122.md) — quest progress + accept HUD unchanged except new label below reward label.
|
||||||
- [NEO-131](NEO-131.md) — reward label transition-only behavior unchanged except rep grant lines.
|
- [NEO-131](NEO-131.md) — reward label transition-only behavior unchanged except rep grant lines.
|
||||||
|
|
||||||
**Full-flow capstone:** [NEO-143](NEO-143.md) extends this with end-to-end Slice 3 faction reputation verification.
|
**Full-flow capstone:** [NEO-143](NEO-143.md) extends [NEO-132](NEO-132.md) with end-to-end Slice 3 faction reputation verification (operator chain **+15** → grid contract **+10** → idempotency). Gate deny remains component QA here (step 6).
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,118 @@
|
||||||
|
# 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-133–NEO-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 **1–19** 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 **3–19** — 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 1–17 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).
|
||||||
|
|
@ -358,8 +358,8 @@ Accepting **`prototype_quest_grid_contract`** before operator-chain completion o
|
||||||
**Acceptance criteria**
|
**Acceptance criteria**
|
||||||
|
|
||||||
- [ ] Human completes **`docs/manual-qa/NEO-143.md`** with server + client.
|
- [ ] Human completes **`docs/manual-qa/NEO-143.md`** with server + client.
|
||||||
- [ ] Epic 7 Slice 3 AC: reputation deltas auditable; gates fail closed on tamper (unknown faction denied at startup).
|
- [x] Epic 7 Slice 3 AC: reputation deltas auditable; gates fail closed on tamper (unknown faction denied at startup) — server automated tests pass; gate deny component QA in [NEO-142](../manual-qa/NEO-142.md).
|
||||||
- [ ] Re-read [epic_07 Slice 3 AC](../decomposition/epics/epic_07_quest_faction.md#slice-3---faction-ledger-pre-production).
|
- [x] Re-read [epic_07 Slice 3 AC](../decomposition/epics/epic_07_quest_faction.md#slice-3---faction-ledger-pre-production).
|
||||||
|
|
||||||
**Client counterpart:** this story **is** the Slice 3 client capstone.
|
**Client counterpart:** this story **is** the Slice 3 client capstone.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,17 @@ Prove Epic 7 Slice 3 acceptance **in Godot**: earn rep from operator chain, acce
|
||||||
## Acceptance criteria checklist
|
## Acceptance criteria checklist
|
||||||
|
|
||||||
- [ ] Human completes **`docs/manual-qa/NEO-143.md`** with server + client.
|
- [ ] Human completes **`docs/manual-qa/NEO-143.md`** with server + client.
|
||||||
- [ ] Epic 7 Slice 3 AC: reputation deltas auditable; gates fail closed on tamper (unknown faction denied at startup).
|
- [x] Epic 7 Slice 3 AC: reputation deltas auditable; gates fail closed on tamper (server tests + NEO-142 gate deny regression).
|
||||||
- [ ] Re-read [epic_07 Slice 3 AC](../decomposition/epics/epic_07_quest_faction.md#slice-3---faction-ledger-pre-production).
|
- [x] Re-read [epic_07 Slice 3 AC](../decomposition/epics/epic_07_quest_faction.md#slice-3---faction-ledger-pre-production).
|
||||||
|
|
||||||
|
## Implementation reconciliation (shipped)
|
||||||
|
|
||||||
|
- **`docs/manual-qa/NEO-143.md`** — five-quest capstone extending NEO-132 with faction standing **15** → grid contract **+10** → idempotency.
|
||||||
|
- **`client/README.md`** — **End-to-end faction reputation loop (NEO-143)** section with flow table and cross-links.
|
||||||
|
- **`docs/manual-qa/NEO-142.md`**, **`docs/manual-qa/NEO-132.md`** — cross-links to NEO-143 Slice 3 capstone.
|
||||||
|
- **`docs/plans/E7M3-pre-production-backlog.md`**, **`E7_M3_FactionReputationLedger.md`**, **`documentation_and_implementation_alignment.md`**, **`module_dependency_register.md`** — E7M3-11 landed; E7.M3 **Ready**; Epic 7 Slice 3 client capstone complete.
|
||||||
|
- **Server regression:** 36 faction-related tests pass (`ReputationOperationsTests`, `FactionGateOperationsTests`, `RewardRouterOperationsTests`).
|
||||||
|
- **No client code changes** — capstone docs-primary; NEO-142 HUD wiring sufficient on `main`.
|
||||||
|
|
||||||
## Technical approach
|
## Technical approach
|
||||||
|
|
||||||
|
|
@ -152,4 +161,4 @@ Document any fix in **Implementation reconciliation** and add regression note to
|
||||||
| **Grid contract instant complete on accept** | Document expected behavior — **`inventory_has_item`** evaluated on **`TryAccept`**; no extra player action after **Shift+Q**. | **adopted** |
|
| **Grid contract instant complete on accept** | Document expected behavior — **`inventory_has_item`** evaluated on **`TryAccept`**; no extra player action after **Shift+Q**. | **adopted** |
|
||||||
| **E7.M3 Ready timing** | Bump module + register to **Ready** only when NEO-143 capstone QA passes (NEO-141 deferred this). | **adopted** |
|
| **E7.M3 Ready timing** | Bump module + register to **Ready** only when NEO-143 capstone QA passes (NEO-141 deferred this). | **adopted** |
|
||||||
| **Five-quest Shift+Q ordering** | After operator chain, only grid contract is eligible **`not_started`** — no catalog-order ambiguity. | **adopted** |
|
| **Five-quest Shift+Q ordering** | After operator chain, only grid contract is eligible **`not_started`** — no catalog-order ambiguity. | **adopted** |
|
||||||
| **Integration gaps on `main`** | Run capstone QA before doc-only land; expect pass with NEO-142 merged. | **pending** — verify during implementation |
|
| **Integration gaps on `main`** | Run capstone QA before doc-only land; expect pass with NEO-142 merged. | **adopted** — no client code changes; server tests pass |
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue