neon-sprawl/docs/plans/NEO-143-implementation-plan.md

165 lines
14 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 — E7M3-11: Playable faction reputation + gate capstone (Godot)
**Linear:** [NEO-143](https://linear.app/neon-sprawl/issue/NEO-143)
**Branch:** `NEO-143-playable-faction-reputation-gate-capstone`
**Backlog:** [E7M3-pre-production-backlog.md](E7M3-pre-production-backlog.md) — **E7M3-11**
**Module:** [E7_M3_FactionReputationLedger.md](../decomposition/modules/E7_M3_FactionReputationLedger.md)
**Pattern:** [NEO-132](NEO-132-implementation-plan.md) — Slice 2 capstone docs-primary; [NEO-142](NEO-142-implementation-plan.md) — faction HUD component landed
**Precursors:** [NEO-142](https://linear.app/neon-sprawl/issue/NEO-142) **`Done`** — standing label, gate deny copy, rep reward lines; [NEO-133](https://linear.app/neon-sprawl/issue/NEO-133)[NEO-141](https://linear.app/neon-sprawl/issue/NEO-141) server faction spine **landed**
**Server counterpart:** NEO-133NEO-141 authoritative faction/rep/gate stack; Bruno is **not** prototype-complete per [full-stack epic decomposition](../../.cursor/rules/full-stack-epic-decomposition.md)
## Goal
Prove Epic 7 Slice 3 acceptance **in Godot**: earn rep from operator chain, accept gated faction quest once; gates fail closed.
## 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-132](NEO-132-implementation-plan.md) precedent; NEO-142 HUD already landed. | **Adopted** — docs-primary |
| **Capstone path** | Extend NEO-132 full flow vs shorter faction-only path? | **Extend full [NEO-132](NEO-132-implementation-plan.md) four-quest flow** + fifth quest **`prototype_quest_grid_contract`** accept/complete — backlog E7M3-11 explicit session; grid contract auto-completes on accept when **`survey_drone_kit`** is already in bag. | **Adopted** — extend NEO-132 |
| **Gate deny verification** | How to satisfy backlog “retry accept gate before rep (denied)” when operator chain grants **+15** atomically? | **Regression to [NEO-142](NEO-142-implementation-plan.md)** (GdUnit + optional dev fixture); capstone main checklist is Godot **success path** only. | **Adopted** — NEO-142 regression |
**Additional defaults (no kickoff question — settled by backlog / landed code):**
- **Session baseline:** fresh **server restart** before Godot **F5** — resets quest progress, faction standing, reward delivery, inventory, skills, encounter state, and resource nodes; **no Bruno/curl** in main capstone checklist.
- **Economy HUD:** toggle **on** for inventory + skill verification (NEO-132 precedent).
- **Five-quest HUD:** **`QuestProgressLabel`** iterates cached quest-definitions catalog — **`prototype_quest_grid_contract`** appears automatically (no hardcoded four-quest list).
- **Shift+Q after operator chain:** catalog order (`id` ordinal) picks **`prototype_quest_grid_contract`** first among eligible **`not_started`** quests (prerequisite operator chain **`completed`**).
- **Server Slice 3 AC** (auditable deltas; tamper fail-closed): verified via **automated regression** reference in manual QA — **`ReputationOperationsTests`**, content CI gates, startup catalog cross-ref — not re-proven in Godot gameplay (NEO-130 / NEO-135 precedent).
## Scope and out-of-scope
**In scope (from Linear + [E7M3-11](E7M3-pre-production-backlog.md#e7m3-11--playable-faction-reputation--gate-capstone-godot)):**
- **`docs/manual-qa/NEO-143.md`**: numbered **single-session** capstone — extend [NEO-132](../manual-qa/NEO-132.md) four-quest + reward flow through faction standing **15****`prototype_quest_grid_contract`** accept/complete → Rust Collective **+10**; Godot restart idempotency for faction standing + quest statuses.
- **`client/README.md`**: **End-to-end faction reputation loop (NEO-143)** section — integration flow table; cross-links NEO-133NEO-142 and Slice 1/2 capstones.
- **Module alignment** (on story completion): [E7_M3](../decomposition/modules/E7_M3_FactionReputationLedger.md) status **Ready**, [documentation_and_implementation_alignment.md](../decomposition/modules/documentation_and_implementation_alignment.md) E7.M3 row, [module_dependency_register.md](../decomposition/modules/module_dependency_register.md) E7.M3 note, [E7M3-pre-production-backlog.md](E7M3-pre-production-backlog.md) E7M3-11 checkboxes; Epic 7 Slice 3 client capstone complete.
- **Integration fixes only if capstone QA fails** on current `main` wiring (faction standing stale, grid-contract accept/complete gap, reward label missing Rust Collective line, etc.).
**Out of scope (from Linear + backlog):**
- Contract generator (E7.M4); zone travel gates (E4.M1); Bruno-only proof.
- New server HTTP routes, store logic, or gate evaluation changes.
- Live gate-deny step in main capstone checklist (deferred to NEO-142 component QA).
- **`GET /game/world/faction-definitions`** client.
**Client counterpart:** this story **is** the Slice 3 client capstone.
## Acceptance criteria checklist
- [ ] Human completes **`docs/manual-qa/NEO-143.md`** with server + client.
- [x] Epic 7 Slice 3 AC: reputation deltas auditable; gates fail closed on tamper (server tests + NEO-142 gate deny regression).
- [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
### 1. Faction + quest freeze reference (E7M3-01)
| Milestone | Quest / action | Rep / standing outcome | Expected HUD |
|-----------|----------------|------------------------|--------------|
| Operator chain **`completed`** | `completionRewardBundle.reputationGrants` | **Grid Operators +15** | **`FactionStandingLabel`**: `Grid Operators: 15`; **`QuestRewardDeliveryLabel`**: `Grid Operators +15 rep` |
| Grid contract accept + complete | `inventory_has_item` **`survey_drone_kit` ×1** (held from operator chain reward) | **Rust Collective +10** on completion | **`FactionStandingLabel`**: `Rust Collective: 10`; **`QuestRewardDeliveryLabel`**: `Rust Collective +10 rep` |
| Gate (component) | Accept grid contract at standing **0** with operator-chain prereq met | **`faction_gate_blocked`** | Readable deny on **`QuestAcceptFeedbackLabel`** — verified in [NEO-142](../manual-qa/NEO-142.md) GdUnit, not main capstone |
**Final standing snapshot (one session):** Grid Operators **15**, Rust Collective **10**.
**Quest roster (five ids, catalog order):** combat intro → gather intro → **grid contract** → operator chain → refine intro.
### 2. Capstone manual QA script (`docs/manual-qa/NEO-143.md`)
**Preconditions:** Same as [NEO-132](../manual-qa/NEO-132.md) — fresh server restart, Godot gameplay only, **`Economy HUD`** on, NEO-142 faction HUD landed on `main`.
**Flow:** Inherit [NEO-132](../manual-qa/NEO-132.md) steps **119** (four quests + reward/economy verification through operator chain). **Extend** with faction + fifth-quest steps:
1. After operator chain completion — assert **`FactionStandingLabel`** **`Grid Operators: 15`**, **`Rust Collective: 0`**; reward label includes **`Grid Operators +15 rep`**.
2. **`Shift+Q`** accept **`prototype_quest_grid_contract`** — accept succeeds; quest **`completed`** (kit already in bag; **`inventory_has_item`** wiring on accept).
3. Assert **`QuestRewardDeliveryLabel`**: `Grid Contract` + **`Rust Collective +10 rep`**.
4. Assert **`FactionStandingLabel`**: **`Rust Collective: 10`** (Grid Operators still **15**).
5. Assert **`QuestProgressLabel`**: all **five** quests **`completed`**.
6. **Capstone snapshot** — record final faction standing + five-quest statuses.
7. **Idempotency** — Godot restart (server still running): five quests still **`completed`**; faction standing unchanged; reward label **`—`**; duplicate **Shift+Q** deny; standing counts unchanged.
8. **Regression pointers:** [NEO-142](../manual-qa/NEO-142.md) gate deny (GdUnit + optional fixture); [NEO-132](../manual-qa/NEO-132.md) reward idempotency; [NEO-123](../manual-qa/NEO-123.md) onboarding chain.
**Server AC (non-Godot):** optional regression subsection — `dotnet test` filters for **`ReputationOperationsTests`**, **`FactionGateOperationsTests`**, **`RewardRouterOperationsTests`** (rep grants); content **`validate_content.py`** / startup fail-fast for unknown faction cross-refs.
### 3. Client README (`client/README.md`)
Add **End-to-end faction reputation loop (NEO-143)** section after [Faction standing + gate feedback HUD (NEO-142)](../../client/README.md#faction-standing--gate-feedback-hud-neo-142), mirroring NEO-132 capstone section:
- One-line Epic 7 Slice 3 capstone goal.
- Flow table: fresh restart → NEO-132 four-quest path → standing **15** → grid contract accept/complete → Rust Collective **+10** → idempotency.
- Cross-links: NEO-133 content freeze, NEO-136NEO-138 rep apply, NEO-139 standing GET, NEO-140 gate/rep projections, NEO-142 HUD, NEO-132 reward capstone.
- Pointer to **`docs/manual-qa/NEO-143.md`**.
- Note: gate deny proof lives in NEO-142 component QA.
### 4. Module / backlog alignment (on land)
When capstone QA passes:
- [E7M3-pre-production-backlog.md](E7M3-pre-production-backlog.md) — E7M3-11 AC checkboxes.
- [E7_M3_FactionReputationLedger.md](../decomposition/modules/E7_M3_FactionReputationLedger.md) — module status **Ready**; Slice 3 client capstone note.
- [documentation_and_implementation_alignment.md](../decomposition/modules/documentation_and_implementation_alignment.md) — E7.M3 row: NEO-143 landed; Epic 7 Slice 3 client capstone complete.
- [module_dependency_register.md](../decomposition/modules/module_dependency_register.md) — E7.M3 **Ready** when capstone lands.
### 5. Integration fixes (conditional)
Run capstone QA on `main` (NEO-142 merged). If any step fails:
| Symptom | Likely fix surface |
|---------|-------------------|
| **`FactionStandingLabel`** stale after grid contract complete | `quest_hud_controller.gd` — faction GET on completion transition (NEO-142 wiring) |
| Grid contract accept denied at standing **15** | Server gate/standing bug — unlikely if NEO-138 Bruno + tests pass |
| Grid contract stays **`active`** after accept with kit in bag | Server **`inventory_has_item`** wiring on accept — file server issue |
| **`QuestRewardDeliveryLabel`** missing Rust Collective line | `quest_hud_controller.gd` rep formatter — unlikely if NEO-142 GdUnit passes |
| Five-quest progress label missing grid contract row | `quest_definitions_client.gd` cache / boot GET — unlikely |
Document any fix in **Implementation reconciliation** and add regression note to manual QA.
## Files to add
| Path | Purpose |
|------|---------|
| `docs/plans/NEO-143-implementation-plan.md` | This plan. |
| `docs/manual-qa/NEO-143.md` | Single-session five-quest faction capstone extending NEO-132 with standing + grid-contract verification + idempotency. |
## Files to modify
| Path | Rationale |
|------|-----------|
| `client/README.md` | **End-to-end faction reputation loop (NEO-143)** section with flow table and cross-links. |
| `docs/manual-qa/NEO-142.md` | Cross-link to NEO-143 as full-flow Slice 3 capstone superset. |
| `docs/manual-qa/NEO-132.md` | Cross-link to NEO-143 faction extension; note standing/grid-contract verification defers to NEO-143. |
| `docs/plans/E7M3-pre-production-backlog.md` | E7M3-11 AC checkboxes when capstone lands. |
| `docs/decomposition/modules/E7_M3_FactionReputationLedger.md` | Module status **Ready** + capstone landed note on completion. |
| `docs/decomposition/modules/documentation_and_implementation_alignment.md` | E7.M3 row: NEO-143 landed; Slice 3 complete. |
| `docs/decomposition/modules/module_dependency_register.md` | E7.M3 **Ready** when capstone lands. |
**Conditional (only if capstone QA fails):** `client/scripts/quest_hud_controller.gd` or `client/scripts/main.gd` — minimal gap-fill; document paths in reconciliation.
## Tests
| Test file | What it covers |
|-----------|----------------|
| *(client unchanged expected)* | NEO-142 GdUnit (`faction_standing_client_test.gd`, `faction_standing_hud_test.gd`) covers standing parse, gate deny copy, rep reward lines. Capstone proof is **`docs/manual-qa/NEO-143.md`** human QA. |
| *(server unchanged)* | Faction spine covered by **`ReputationOperationsTests`**, **`FactionGateOperationsTests`**, **`RewardRouterOperationsTests`**, **`QuestAcceptApiTests`**, content **`validate_content.py`**. Optional regression command in manual QA notes. |
## Open questions / risks
| Question / risk | Agent recommendation | Status |
|-----------------|----------------------|--------|
| **Gate deny in capstone vs NEO-142** | Main NEO-143 checklist is success path; deny proof stays NEO-142 component QA (user adopted). | **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** |
| **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. | **adopted** — no client code changes; server tests pass |