165 lines
14 KiB
Markdown
165 lines
14 KiB
Markdown
# 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-133–NEO-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-133–NEO-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 **1–19** (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-136–NEO-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 |
|