# E7.M3 — FactionReputationLedger ## Summary | Field | Value | |--------|--------| | **Module ID** | E7.M3 | | **Epic** | [Epic 7 — Quest / Faction](../epics/epic_07_quest_faction.md) | | **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)). Slice 3 backlog **E7M3-10** [NEO-142](https://linear.app/neon-sprawl/issue/NEO-142) → **E7M3-11** [NEO-143](https://linear.app/neon-sprawl/issue/NEO-143). Upstream: E7.M1 **Ready**, E7.M2 **Ready**. | | **Linear** | Label **`E7.M3`** · [E7M3-pre-production-backlog.md](../../plans/E7M3-pre-production-backlog.md) | ## Purpose Character-wide **faction standing**, auditable **reputation deltas**, and **`FactionGateRule`** evaluation for quest accept (and future zone/travel gates via [E4.M1](E4_M1_ZoneGraphAndTravelRules.md)). Rep grants flow through [E7.M2](E7_M2_RewardAndUnlockRouter.md) **`completionRewardBundle`** idempotency. ## Responsibilities - Persist **`FactionStanding`** per player per faction; apply **`ReputationDelta`** with clamp and audit log. - Evaluate **`FactionGateRule`** on quest accept — fail closed on unknown faction or tampered rules (startup validation). - Emit telemetry hook sites: **`reputation_delta`**, **`faction_gate_blocked`**. ## Key contracts | Contract | Role | |----------|------| | `FactionDef` | Faction id, display name, min/max/neutral standing. | | `FactionStanding` | Current rep per faction for a player. | | `ReputationDelta` | Signed change with source attribution (quest id, etc.). | | `FactionGateRule` | Minimum standing required (e.g. on `QuestDef`). | | `reputationGrants` | Rows on `QuestRewardBundle` — `factionId` + `amount`. | ## Module dependencies - **E7.M1** — QuestStateMachine (`TryAccept` gate hook site). - **E7.M2** — RewardAndUnlockRouter (bundle apply + idempotent delivery store). ## Dependents (by design) - **E7.M4** — ContractMissionGenerator. - **E8.M2** — GuildCorpProgressionState. - **E4.M1** — ZoneGraphAndTravelRules (`TravelRule` faction gates). ## Related implementation slices Epic 7 **Slice 3** — at least one faction quest line with rep grant + gated accept; auditable deltas; telemetry **`reputation_delta`**, **`faction_gate_blocked`**. Backlog: [E7M3-pre-production-backlog.md](../../plans/E7M3-pre-production-backlog.md). ## Linear backlog (decomposed) | Slug | Linear | |------|--------| | E7M3-01 | [NEO-133](https://linear.app/neon-sprawl/issue/NEO-133) | | E7M3-02 | [NEO-134](https://linear.app/neon-sprawl/issue/NEO-134) | | E7M3-03 | [NEO-135](https://linear.app/neon-sprawl/issue/NEO-135) | | E7M3-04 | [NEO-136](https://linear.app/neon-sprawl/issue/NEO-136) | | E7M3-05 | [NEO-137](https://linear.app/neon-sprawl/issue/NEO-137) | | E7M3-06 | [NEO-138](https://linear.app/neon-sprawl/issue/NEO-138) | | E7M3-07 | [NEO-139](https://linear.app/neon-sprawl/issue/NEO-139) | | E7M3-08 | [NEO-140](https://linear.app/neon-sprawl/issue/NEO-140) | | E7M3-09 | [NEO-141](https://linear.app/neon-sprawl/issue/NEO-141) | | E7M3-10 | [NEO-142](https://linear.app/neon-sprawl/issue/NEO-142) | | E7M3-11 | [NEO-143](https://linear.app/neon-sprawl/issue/NEO-143) | ## Prototype Slice 3 freeze (E7M3-01) ### Faction catalog | `FactionDef.id` | `displayName` | Standing band | |-----------------|---------------|---------------| | **`prototype_faction_grid_operators`** | Grid Operators | -100…100 (neutral 0) | | **`prototype_faction_rust_collective`** | Rust Collective | -100…100 (neutral 0) | ### Quest content changes | `QuestDef.id` | Rep / gate | |---------------|------------| | **`prototype_quest_operator_chain`** | **`completionRewardBundle.reputationGrants`**: **`prototype_faction_grid_operators`** **+15** (existing item + skill XP unchanged) | | **`prototype_quest_grid_contract`** *(new)* | **`prerequisiteQuestIds`**: operator chain; **`factionGateRules`**: Grid Operators **`minStanding` 15**; objective **`inventory_has_item`** **`survey_drone_kit` ×1**; completion rep **Rust Collective +10** | **Roster:** five quests total (four E7.M1 onboarding + one faction line). E7.M1 four-quest freeze expands under E7M3 CI gates (`PROTOTYPE_E7M3_QUEST_IDS` in `scripts/validate_content.py`). **CI enforcement (NEO-133):** `scripts/validate_content.py` validates `content/factions/*_factions.json`, five-quest roster, faction cross-refs on gates and `reputationGrants`, E7M3 completion bundle freeze, and grid-contract shape. ## Source anchors - Master plan: [`neon_sprawl_vision.plan.md`](../../../neon_sprawl_vision.plan.md) — Epic 7, faction reputation. - Game design: [skills.md — Rep / story](../../../docs/game-design/skills.md) (character-wide faction rep). - [Module dependency register](module_dependency_register.md)