From c2fa15dbe3142fcf0252b91af4bb205a51f64a52 Mon Sep 17 00:00:00 2001 From: Trevor Date: Fri, 17 Jul 2026 07:51:35 -0700 Subject: [PATCH] Document Phase 2A2a shared gameplay contract proposals. Propose ASC resource, authority, damage/death/respawn, and related contracts for owner review without approving or implementing them. Co-authored-by: Cursor --- .../Phase2/02-Phase2A-OpenDecisions.md | 78 +- .../Phase2/03-SharedGameplayContracts.md | 1242 +++++++++++++++++ .../Phase2/04-Phase2A-DecisionRegister.md | 342 +++++ 3 files changed, 1659 insertions(+), 3 deletions(-) create mode 100644 Documentation/Phase2/03-SharedGameplayContracts.md create mode 100644 Documentation/Phase2/04-Phase2A-DecisionRegister.md diff --git a/Documentation/Phase2/02-Phase2A-OpenDecisions.md b/Documentation/Phase2/02-Phase2A-OpenDecisions.md index fbf10566..86ca6084 100644 --- a/Documentation/Phase2/02-Phase2A-OpenDecisions.md +++ b/Documentation/Phase2/02-Phase2A-OpenDecisions.md @@ -4,11 +4,82 @@ |---|---| | Status | Draft | | Date | 2026-07-17 | -| Git commit | `aa0058a0` | -| Rule | Options listed only — **none selected** in this batch | +| Phase 2A1 Git commit | `aa0058a0` | +| Phase 2A2a reconciliation commit base | `9919faab` | +| Rule | Options listed in the historical table were not selected in Phase 2A1. Phase 2A2a adds **Proposed** contract links only — **none Approved**. | Decisions that remain open after Phase 1 static archaeology plus Phase 2A1 runtime evidence. Do not treat this document as an approved architecture contract. +--- + +## Phase 2A2a reconciliation + +| Field | Value | +|---|---| +| Pass | 2A2a — Evidence-to-contract reconciliation | +| Status | Draft | +| Contract document | [`03-SharedGameplayContracts.md`](03-SharedGameplayContracts.md) | +| Decision register | [`04-Phase2A-DecisionRegister.md`](04-Phase2A-DecisionRegister.md) | + +### Classification of each Phase 2A1 open decision + +| Decision | Classification | Contract link(s) | Notes | +|---|---|---|---| +| Canonical health source of truth | Addressed by Proposed Contract | [C-001](03-SharedGameplayContracts.md#c-001--canonical-player-resource-source-of-truth) | ASC sole SoT Proposed; not Approved | +| Canonical mana source of truth | Addressed by Proposed Contract | [C-001](03-SharedGameplayContracts.md#c-001--canonical-player-resource-source-of-truth), [C-003](03-SharedGameplayContracts.md#c-003--resource-access-boundary) | Merged into C-001 resource SoT + C-003 access | +| Canonical stamina source of truth | Addressed by Proposed Contract | [C-001](03-SharedGameplayContracts.md#c-001--canonical-player-resource-source-of-truth), [C-002](03-SharedGameplayContracts.md#c-002--character-default-attribute-initialization) | ASC SoT Proposed; UI deferred via C-013; whether stamina required for 2B remains design-adjacent | +| Temporary legacy mirror during reconstruction | Addressed by Proposed Contract | [C-004](03-SharedGameplayContracts.md#c-004--legacy-compatibility-policy) | ASC→legacy one-way Recommended; bidirectional Rejected by Existing Evidence | +| Where damage must enter shared framework | Addressed by Proposed Contract + Blocked by Missing Runtime Evidence | [C-005](03-SharedGameplayContracts.md#c-005--damage-contract) | Boundary Proposed; runtime damage path not exercised (RE-2A1-022) | +| Where death threshold evaluation must occur | Addressed by Proposed Contract + Blocked by Missing Runtime Evidence | [C-007](03-SharedGameplayContracts.md#c-007--death-contract) | ASC Health ≤ 0 Proposed; death PIE not run | +| Whether AnimNotifies may trigger authoritative gameplay | Addressed by Proposed Contract + Blocked by Missing Runtime Evidence | [C-009](03-SharedGameplayContracts.md#c-009--authority-contract), [C-010](03-SharedGameplayContracts.md#c-010--animation-responsibility-contract) | Notify-as-sole-authority prohibited as end state; chain not observed | +| Required interruption and cleanup contract | Addressed by Proposed Contract + Blocked by Missing Runtime Evidence | [C-011](03-SharedGameplayContracts.md#c-011--ability-lifecycle-and-cleanup-contract) | Lifecycle Proposed; interrupt test blocked (RE-2A1-020) | +| Required respawn and HUD lifecycle contract | Addressed by Proposed Contract + Blocked by Missing Runtime Evidence | [C-008](03-SharedGameplayContracts.md#c-008--respawn-contract), [C-013](03-SharedGameplayContracts.md#c-013--hud-data-flow-contract) | GM/PC ownership + Overlay-only Proposed; RT-006 blocked | +| Pickup authority model | Addressed by Proposed Contract + Blocked by Test Environment | [C-014](03-SharedGameplayContracts.md#c-014--pickup-authority-and-replication-contract) | Server authority Proposed; overlap/2P not run | +| PlayerState versus pawn ownership boundaries | Addressed by Proposed Contract | [C-012](03-SharedGameplayContracts.md#c-012--playerstate-and-pawn-ownership-contract) | Keep ASC on PlayerState Proposed; enemy accessor still defective | +| How to enable 2-client PIE for remaining evidence | Blocked by Test Environment | — (environment / harness; not a gameplay SoT contract) | See still-blocked list; C-015 observability | +| Enhanced Input injection for automated ability tests | Blocked by Test Environment | — (harness; blocks validation of C-009/C-010/C-011) | See still-blocked list | + +### Duplicate / superseded handling + +| Topic | Classification | Disposition | +|---|---|---| +| Separate health / mana / stamina “canonical SoT” rows | Duplicate (resolved into one contract) | Historical rows retained below; proposal unified under **C-001** (+ init C-002, access C-003) | +| Legacy mirror vs dual SoT options overlapping C-001 | Superseded by C-004 recommendation | Historical options retained; recommendation lives in contracts/register | + +### Explicit remaining blocked runtime areas + +These remain **explicitly blocked** and must stay visible until evidence exists. Tool inaccessibility is **not** runtime absence. + +| Area | Status | Evidence IDs | +|---|---|---| +| Enhanced Input ability execution | Blocked by Test Environment / Tool Limitation | RE-2A1-015, 019, 021 | +| AnimNotify authority | Blocked by Missing Runtime Evidence | RE-2A1-019, 021 (chain not executed) | +| Ability cost mutation | Blocked by Missing Runtime Evidence / Tool Limitation | RE-2A1-014, 015 | +| Ability interruption | Blocked by Test Environment | RE-2A1-020 | +| Player damage / death / respawn | Blocked by Missing Implementation / Tool Limitation | RE-2A1-022 | +| Two-client replication | Blocked by Test Environment / Tool Limitation | RE-2A1-023–026 | +| Remote character selection | Blocked by Test Environment | Depends on multi-client (RE-2A1-023) | +| Pickup authority and visibility | Blocked by Test Environment / Tool Limitation | RE-2A1-017, 018 | +| Enemy attribute mutation | Blocked by Missing Runtime Evidence / Tool Limitation | RE-2A1-028, 030 | +| Session behavior | Still Open (Phase 2E scope) | Not closed by 2A1; outside 2A2a contracts | + +### New defects and limitations accounted for in contracts + +| Observation | Contract handling | +|---|---| +| `PlayerFirstSpawn` Accessed None during normal spawn; spawn still succeeds | C-008 failure modes / transitional spawn path | +| Amazonian vs Paladin legacy defaults differ; both legacy health begin at 0 | C-001, C-004; death-threshold risk under C-007 | +| ASC defaults stable across inspected characters; no active default GE; no granted GAs | C-002 | +| Enhanced Input unavailable via current automation | C-009–C-011 validation blocked; C-015 | +| Multi-client PIE unavailable via authorized tooling | C-009, C-014 validation blocked; env decisions remain | +| Enemy attributes inaccessible via current inspector | C-012 / C-015 — tool limit ≠ absence (RE-2A1-027 vs 028) | + +--- + +## Historical Phase 2A1 open-decision table (preserved) + +The following table is the Phase 2A1 inventory. It is preserved for evidence continuity. Classifications above supersede “options only” for proposal purposes; **no option is Approved**. + | Decision | Static evidence | Runtime evidence | Options | Blocking unknown | Required approval | |---|---|---|---|---|---| | Canonical health source of truth | Dual pools: ASC `Health`/`MaxHealth` vs `DEPRECATED_CurrentHealth`/`MaxHealth`; combat uses legacy; potions use ASC | ASC init 75/100 confirmed; Amazonian/Paladin legacy Current/Max Health = **0** at spawn; Overlay binds ASC | A) ASC only immediately B) Legacy only during reconstruction C) ASC canonical with temporary legacy mirror D) Character-specific transitional policy | Whether death/combat must keep working on legacy-zero characters before mirror | Phase 2A2 architecture contract | @@ -31,7 +102,8 @@ Decisions that remain open after Phase 1 static archaeology plus Phase 2A1 runti - Final attribute set schema changes - Whether to delete `DEPRECATED_*` in Phase 2A - Per-character reconstruction order changes +- Approval of any C-001–C-015 contract (owner action required) ## Next authorized step (outside this batch) -Begin Phase 2A2 only after explicit authorization: propose shared resource/authority/damage/death/cleanup contracts using these open rows — still no implementation until contracts are approved. +Wait for explicit owner approval of Proposed contracts before Phase 2A2b, Phase 2A3 implementation planning, or any Unreal implementation. Do not begin Phase 2B. diff --git a/Documentation/Phase2/03-SharedGameplayContracts.md b/Documentation/Phase2/03-SharedGameplayContracts.md new file mode 100644 index 00000000..f3a91452 --- /dev/null +++ b/Documentation/Phase2/03-SharedGameplayContracts.md @@ -0,0 +1,1242 @@ +# Phase 2A2a — Shared Gameplay Contracts + +| Field | Value | +|---|---| +| Status | Draft | +| Date | 2026-07-17 | +| Phase | 2A2a — Shared gameplay contract proposal | +| Starting Git commit | `9919faab` | +| Engine | Unreal Engine 5.8 | +| Rule | All contracts are **Proposed**. None are Approved. No implementation in this pass. | + +## Purpose + +Translate accepted Phase 1 static archaeology and Phase 2A1 runtime evidence into proposed shared gameplay contracts. These contracts define architectural boundaries for review. They do not authorize implementation, asset changes, or Phase 2B. + +## Evidence vocabulary + +| Label | Meaning | +|---|---| +| Static evidence | Phase 1 archaeology observation | +| Runtime evidence | Phase 2A1 observed runtime behavior or tool limitation | +| Tool limitation | Cannot observe because tooling/environment blocked the path | +| Inference | Reasonable conclusion not directly proven | +| Recommendation | Proposed architectural choice (not observed fact) | +| Required approval | Exact question for the project owner | +| Deferred validation | Runtime test still required before trusting the rule | + +## Decision states used in this pass + +Proposed · Alternative · Deferred · Blocked by Runtime Evidence · Blocked by Design Decision · Rejected by Existing Evidence + +**Do not use Approved.** + +## Continuity + +| Check | Result | +|---|---| +| Phase 2A1 evidence reviewed | Yes — `00`, `01`, `02` under `Documentation/Phase2/` | +| Starting `git rev-parse HEAD` | `9919faab4aa667cad4b4156bfa46c2d9f2113e40` | +| Working tree at start | Clean | + +Cross-links: [`00-Phase2A-RuntimeBaseline.md`](00-Phase2A-RuntimeBaseline.md), [`01-Phase2A-RuntimeEvidenceIndex.md`](01-Phase2A-RuntimeEvidenceIndex.md), [`02-Phase2A-OpenDecisions.md`](02-Phase2A-OpenDecisions.md), [`04-Phase2A-DecisionRegister.md`](04-Phase2A-DecisionRegister.md). + +--- + +# C-001 — Canonical player resource source of truth + +**State:** Proposed + +### Problem being solved + +Combat, death, ability costs, potions, and HUD currently read different resource stores. ASC and DEPRECATED Blueprint values diverge immediately after spawn, so UI and combat can disagree. + +### Current implementation + +- Player ASC + AttributeSet live on `ARIRPlayerState`. +- Overlay HUD binds ASC Health/Mana. +- Abilities and Amazonian inbound damage use DEPRECATED floats (`DEPRECATED_CurrentHealth`, mana costs, etc.). +- Consumable GEs modify ASC attributes only. +- No sync between ASC and DEPRECATED pools. + +### Confirmed evidence + +| Kind | Evidence | +|---|---| +| Static | Docs `05`, `06` §8, `01` P0 dual-resource risk — combat uses legacy; potions/Overlay use ASC; sync Missing | +| Runtime | RE-2A1-001/012: ASC Health 75/100, Mana 25/50, Stamina 0/0 for Amazonian and Paladin | +| Runtime | RE-2A1-004/005: Amazonian legacy health/mana 0; stamina 85/100 | +| Runtime | RE-2A1-013: Paladin legacy Mana 100/100 vs ASC 25/50; legacy Health 0/0 | +| Runtime | RE-2A1-002/003: no active GEs; no granted GAs at spawn | +| Inference | Amazonian AnyDamage writing legacy health=0 is at immediate death-threshold risk if that path fires | + +### Proposed rule + +ASC attributes are the **sole canonical source of truth** for Health, MaxHealth, Mana, MaxMana, Stamina, and MaxStamina. DEPRECATED Blueprint resource variables are **not authoritative**. UI, costs, healing, damage, death, and gameplay gating ultimately read the canonical ASC attributes. + +Spawn divergence is treated as a **confirmed dual-store defect**, not two valid truths. + +### Allowed behavior + +- Reading ASC attributes for gameplay and UI. +- Writing ASC attributes through shared authoritative boundaries (C-003, C-005, C-006). +- Temporary ASC→legacy shadow copies for unconverted read-only consumers (C-004). + +### Prohibited behavior + +- Treating DEPRECATED floats as authoritative for new gameplay. +- UI or death decisions driven solely by DEPRECATED values after cutover. +- Silent acceptance of ASC/legacy disagreement as intended design. + +### Transitional behavior + +Until each consumer is migrated, an ASC→legacy one-way shadow may keep unconverted readers consistent (C-004). Legacy writers must be migrated or blocked before they can overwrite ASC. + +### Dependencies + +C-002 (initialization), C-003 (access boundary), C-004 (legacy policy). + +### Migration impact + +Ability costs, Amazonian AnyDamage/death, Cleric heal, Overlay (already ASC), any remaining `Server_UpdateHUD` callers, future stamina systems. + +### Runtime validation required + +- After init policy lands: ASC and any permitted shadow values match at spawn for each playable. +- Potion heal changes ASC and Overlay; combat damage changes ASC Health. +- Death fires from ASC Health ≤ 0, not legacy zero alone. + +### Failure modes + +- Partial migration leaves one system on ASC and another on legacy → desync returns. +- Shadow omitted while legacy death still active → false immediate death or immortal combat. + +### Approval question + +**Do you approve ASC AttributeSet as the sole canonical source of truth for Health, MaxHealth, Mana, MaxMana, Stamina, and MaxStamina, with DEPRECATED Blueprint resource variables treated as non-authoritative?** + +--- + +# C-002 — Character default attribute initialization + +**State:** Proposed (recommended option A) + +### Problem being solved + +All inspected characters spawn with identical native ASC defaults. Orphan character default GEs are unreferenced. Stamina ASC remains 0/0. Missing character defaults fail silently via native Init*, producing incorrect balance and hiding misconfiguration. + +### Current implementation + +- `URIRAttributeSet` ctor: InitHealth(75), InitMaxHealth(100), InitMana(25), InitMaxMana(50); Stamina/MaxStamina not Init'd. +- `BP_PlayerState.DefaultAttributesGameplayEffect` = None. +- Orphan GEs (`GE_*_DefaultAttributes`) exist per character but have **0 referencers** and do not modify Max* attributes. +- Legacy CDO defaults differ per character (Amazonian stamina 85/100; Paladin mana 100/100; both health 0). + +### Confirmed evidence + +| Kind | Evidence | +|---|---| +| Static | Doc `06` §§2–4 — orphan default GEs; native Init fallback; Max* absent on default GEs | +| Runtime | RE-2A1-001/012 — ASC identical for Amazonian and Paladin | +| Runtime | RE-2A1-002 — no active default GE at spawn | +| Runtime | RE-2A1-011 — CDO explains legacy zeros / character-specific legacy stamina/mana | +| Tool limitation | N/A for spawn values (observed) | + +### Options compared + +| Option | Description | Fit to evidence | +|---|---|---| +| **A. Character-specific default GE** | Pawn/class selects a default GE; server applies after ASC actor info valid | Best fit — assets and `DefaultAttributesGameplayEffect` property already exist | +| B. Shared init GE + SetByCaller | One GE; magnitudes passed per class | Viable; fewer assets; more native glue | +| C. Native initialization service | Explicit server service sets all six attrs | Viable; strongest fail-visible control; bypasses existing GE assets | +| D. Other | e.g. hybrid GE for currents + native Max* | Possible but adds dual paths | + +### Proposed rule (Recommendation: Option A) + +Character defaults are applied on the **authoritative server** only after ASC OwnerActor/AvatarActor are valid. Every character receives **explicit** current and maximum Health, Mana, and Stamina. Stamina may not rely on an uninitialized native default. Initialization must be deterministic on initial spawn and respawn. A missing character default assignment must **fail visibly** (log/assert/fatal in development) rather than silently falling back to identical native Init* values. + +Existing orphan GEs must be completed (including MaxHealth/MaxMana/MaxStamina) before they are treated as production defaults. Incomplete GEs are migration work, not a license to keep silent Init*. + +**Alternatives retained:** B, C (Proposed alternatives, not rejected). + +### Allowed behavior + +- Server ApplyGameplayEffect of character default GE after InitAbilityActorInfo. +- Explicit Max* and current values in that GE (or immediate companion apply). +- Visible failure when class data / GE assignment is missing. + +### Prohibited behavior + +- Silent native-only fallback that leaves all classes at 75/100/25/50/0/0. +- Client-authoritative default attribute application. +- Relying on uninitialized Stamina ASC as “zero by design” without an explicit assignment. + +### Transitional behavior + +Until GEs are completed, temporary use of Option C for Max* fill is acceptable only if documented as transitional and still fails visibly when class data is missing. + +### Dependencies + +C-001, C-012 (ASC on PlayerState / re-init on possess). + +### Migration impact + +`ARIRPlayerState`, character class data, orphan `GE_*_DefaultAttributes`, spawn and respawn paths, Gunslinger (no GE today). + +### Runtime validation required + +- Per playable: ASC currents and maxes match class policy after spawn and after respawn. +- Missing GE assignment produces a visible error in a controlled test. +- No active unintended GEs beyond the intended default apply. + +### Failure modes + +- GE overrides current without Max* → clamps/UI break. +- Apply before actor info valid → no-op or wrong Owner. +- Respawn skips reapply → stale or zeroed attributes. + +### Approval question + +**Do you approve Option A (character-specific default Gameplay Effect applied server-side after ASC actor info is valid), with visible failure on missing assignment and mandatory explicit current+max Health/Mana/Stamina?** + +--- + +# C-003 — Resource-access boundary + +**State:** Proposed + +### Problem being solved + +Gameplay mutates resources through ad-hoc Blueprint variables, `FCanUseMana`, `ApplyDamage`, and GEs without a single authoritative interface. Incremental migration risks two authoritative stores. + +### Current implementation + +- Ability graphs read/write DEPRECATED mana/health/damage floats. +- Potions apply ASC GEs via EffectActor. +- Overlay reads ASC. +- No shared resource API above ASC for costs/affordability. + +### Confirmed evidence + +| Kind | Evidence | +|---|---| +| Static | Docs `05` resource inventory; `06` legacy/GAS boundary; `07` S9 | +| Runtime | RE-2A1-001–005, 012–013 — dual values at spawn | +| Runtime | Ability cost mutation path not exercised (RE-2A1-015/019/021 Tool Limitation) | + +### Proposed rule + +New gameplay may not directly read or write DEPRECATED resource variables. Resource reads, affordability checks, costs, restoration, and maximum-value queries use a **shared authoritative interface** that operates on ASC attributes. Cost validation and mutation occur **atomically on the server**. + +### Allowed behavior + +- Server: check affordability → commit cost → proceed, or fail without partial mutation. +- Reads of current/max via the shared interface. +- Migrated abilities calling the interface instead of DEPRECATED floats. + +### Prohibited behavior + +- New code writing DEPRECATED resource vars as authority. +- Client-side cost commitment. +- Dual-write of ASC and DEPRECATED as both authoritative. + +### Transitional behavior + +Migrate each dependent path to the interface **before** that path is considered converted. Until conversion, that path may still touch DEPRECATED vars under C-004 constraints, but must not invent a second ASC writer. Prefer converting cost/death/heal writers first. + +### Dependencies + +C-001, C-002, C-004, C-006. + +### Migration impact + +`FCanUseMana`, all DEPRECATED_*ManaCost call sites, RecoverPlayerHealth, Amazonian AnyDamage, future GA costs. + +### Runtime validation required + +- Ability cost reduces ASC Mana once; Overlay updates; legacy shadow (if present) matches. +- Failed affordability leaves attributes unchanged. + +### Failure modes + +- Interface bypass leaves stray DEPRECATED writers. +- Non-atomic check-then-spend races under replication. + +### Approval question + +**Do you approve a shared server-authoritative ASC resource interface as the only allowed read/write path for new gameplay resource access, with atomic cost validation and mutation?** + +--- + +# C-004 — Legacy compatibility policy + +**State:** Proposed (recommended option C; bidirectional Rejected by Existing Evidence) + +### Problem being solved + +Unconverted legacy readers still exist while ASC is becoming canonical. Bidirectional sync would create competing writers and feedback loops. Legacy writers must not silently overwrite ASC. + +### Current implementation + +No sync code. ASC and DEPRECATED diverge at spawn. Overlay uses ASC; combat vars use legacy. + +### Confirmed evidence + +| Kind | Evidence | +|---|---| +| Static | Doc `06` — legacy-resource synchronization Missing | +| Runtime | RE-2A1-004/005/013 — divergent spawn values | +| Inference | Bidirectional sync with Amazonian health=0 and ASC=75 would create writer conflict | + +### Options evaluated + +| Option | Verdict | +|---|---| +| A. Bidirectional synchronization | **Rejected by Existing Evidence** — competing writers; feedback-loop risk | +| B. Legacy→ASC synchronization | Rejected as primary policy — would promote non-authoritative / zeroed legacy into ASC | +| **C. ASC→legacy one-way shadow** | **Recommended (Proposed)** for temporary unconverted read-only consumers | +| D. No synchronization; migrate each path before use | Preferred when a path can cut over in one change; compatible with C | + +### Proposed rule + +Temporary **one-way ASC→legacy** compatibility shadows are allowed only where an unconverted **read-only** consumer still requires DEPRECATED floats. Legacy **direct writers** must not silently overwrite canonical ASC values. Prefer Option D cutover when feasible. Bidirectional sync is prohibited. + +### Allowed behavior + +- After ASC mutation, optionally push values into DEPRECATED vars for legacy UI/gates not yet migrated. +- Document each shadow consumer and remove it when migrated. + +### Prohibited behavior + +- Bidirectional sync. +- Legacy AnyDamage / cost writers updating ASC without going through C-003/C-005/C-006. +- Indefinite shadow without a migration owner. + +### Transitional behavior + +Shadow is temporary scaffolding during reconstruction. Each shadowed consumer must be listed and retired. + +### Dependencies + +C-001, C-003. + +### Migration impact + +Amazonian AnyDamage, `FCanUseMana` readers, `Server_UpdateHUD` callers, any BP reading DEPRECATED health/mana. + +### Runtime validation required + +- With shadow on: after ASC heal/damage, shadowed legacy matches ASC. +- Legacy writer attempt cannot change ASC without shared boundary. + +### Failure modes + +- Forgotten shadow → legacy death on zero. +- Accidental reverse write → ASC corrupted. + +### Approval question + +**Do you approve ASC→legacy one-way shadow only for temporary read-only consumers, with bidirectional sync prohibited and legacy writers forbidden from silently overwriting ASC?** + +--- + +# C-005 — Damage contract + +**State:** Proposed (ExecutionCalculation design Deferred) + +### Problem being solved + +Player damage uses `ApplyDamage` into legacy health (Amazonian) or has no enemy consumer. Potions use ASC GEs. There is no single server entry for validated damage. + +### Current implementation + +- Paladin/Amazonian/Cleric UseAbility* / ChargeBox: Authority `ApplyDamage`. +- Amazonian `ReceiveAnyDamage` subtracts DEPRECATED_CurrentHealth. +- Enemy: no ReceiveAnyDamage / health mutation (Implementation Missing). +- No project GameplayEffectExecutionCalculation subclasses. + +### Confirmed evidence + +| Kind | Evidence | +|---|---| +| Static | Docs `05`, `09`, `06` — ApplyDamage vs missing enemy reception; ASC Health unbridged | +| Runtime | RE-2A1-022 — player damage/death path blocked (enemy attack Missing; ability input Tool Limitation) | +| Runtime | RE-2A1-027/030 — enemy components present; damage reception not observed | + +### Proposed rule + +One **server-authoritative damage entry boundary** for player and enemy targets: + +| Step | Owner | +|---|---| +| Who may request damage | Abilities, overlaps, environmental actors, future AI — as **requests** only | +| Who validates | Server damage boundary | +| Target validity | Server (alive, damageable, team/filter rules) | +| Magnitude calculation | Server (data asset / ability / curve — implementation later) | +| Mitigation | Server (block/armor tags — design later) | +| Health change | Server writes **ASC Health** via shared resource path | +| Instigator / causer | Recorded on the authoritative damage event | +| Duplicate prevention | Server dedupe (e.g. ability instance / window / hit ID) | +| Death evaluation | Trigger C-007 after Health change | +| Legacy ApplyDamage | Transitional **adapter** into this boundary; not a second SoT | + +**Not chosen now:** final GameplayEffectExecutionCalculation design. Retained as Alternative for later approval if GAS execution is preferred after 2B. + +### Allowed behavior + +- Server-only Health reduction through the boundary. +- Transitional ApplyDamage → adapter → ASC. +- Presentation multicast after authoritative apply. + +### Prohibited behavior + +- Client-authoritative Health writes. +- AnimNotify as sole damage authority without server validation (see C-009/C-010). +- Damage that mutates only DEPRECATED health after cutover. + +### Transitional behavior + +Keep Authority-gated UseAbility ApplyDamage call sites temporarily, but route Health mutation into ASC via adapter. Enemy reception remains blocked until Phase 2D implements the consumer under this contract. + +### Dependencies + +C-001, C-003, C-007, C-009. Enemy consumers: Phase 2D. + +### Migration impact + +All ApplyDamage call sites; Amazonian AnyDamage; future enemy inbound damage; block absorb design (Paladin 002). + +### Runtime validation required + +- Controlled damage reduces ASC Health once; Overlay updates; no double apply. +- Death triggers at ASC ≤ 0. +- **Blocked today:** ability-driven and enemy-driven damage (Tool Limitation / Missing Implementation). + +### Failure modes + +- Adapter forgotten → legacy and ASC diverge again. +- No dedupe → double hits from multicast notifies. + +### Approval question + +**Do you approve a single server-authoritative damage entry that writes ASC Health, with legacy ApplyDamage limited to a transitional adapter, and ExecutionCalculation design deferred?** + +--- + +# C-006 — Healing and resource restoration contract + +**State:** Proposed + +### Problem being solved + +Healing exists as Cleric `RecoverPlayerHealth` (legacy) and consumable GEs (ASC). No shared clamp/attribution policy. + +### Current implementation + +- Cleric UseAbility002: Authority heal via DEPRECATED recover interface. +- Potions/food: GE Instant/Duration on ASC Health/Mana. +- No AttributeSet PostGameplayEffectExecute clamp-to-max. + +### Confirmed evidence + +| Kind | Evidence | +|---|---| +| Static | Docs `05` Cleric 002; `06` GE inventory; `12` pickups | +| Runtime | RE-2A1-018 — consumable overlap not executed (movement/input blocked) | +| Runtime | ASC MaxHealth/MaxMana exist; Overlay binds them | + +### Proposed rule + +- Restoration is **server-authoritative**. +- Values clamp to the attribute’s Max* unless an approved GE explicitly documents over-resource permission. +- Source attribution recorded (instigator, GE class, ability ID). +- Gameplay Effects and shared restore services both enter the **same resource boundary** (C-003). +- UI updates only by observing replicated ASC changes. +- Overheal / over-mana / over-stamina **not permitted** by default. +- Consumables use the same boundary (apply GE or service on server). + +### Allowed behavior + +- Server GE heal/mana restore; shared RestoreResource API; clamp to max. +- Cosmetic feedback after authoritative change. + +### Prohibited behavior + +- Client-side Health/Mana increases. +- Unclamped restores that leave Current > Max without explicit approval. +- Healing only DEPRECATED health while ASC remains unchanged. + +### Transitional behavior + +Cleric recover path adapts to ASC via C-003; potions already on ASC remain preferred pattern. + +### Dependencies + +C-001, C-003, C-014 (pickup apply). + +### Migration impact + +Cleric 002, EffectActor GEs, any DEPRECATED recover paths, future HoT/MoT. + +### Runtime validation required + +- Heal at full Health does not exceed MaxHealth. +- Potion +25 Health updates ASC and Overlay once. +- **Blocked today:** pickup overlap apply (RE-2A1-018). + +### Failure modes + +- Dual heal systems → Overlay shows ASC heal while combat uses legacy. +- Missing clamp → invalid Current > Max. + +### Approval question + +**Do you approve server-authoritative restoration through the shared ASC resource boundary, clamping to Max* by default, with consumables and ability heals using the same path?** + +--- + +# C-007 — Death contract + +**State:** Proposed + +### Problem being solved + +Death is evaluated from DEPRECATED health on Amazonian; ASC Health is unused for death. Animation can force enemy `IsDead` false. No idempotent shared death transition. + +### Current implementation + +- Amazonian: AnyDamage → subtract DEPRECATED_CurrentHealth → PlayerDeath if ≤ 0. +- Base: PlayerDeath / Client_PlayerDeath / IsDead replicated bool. +- Enemy ABP forces IsDead false every update; no damage reception. +- `State.Dead` tag Present but Unreferenced. + +### Confirmed evidence + +| Kind | Evidence | +|---|---| +| Static | Docs `05` Amazonian death; `09` enemy death incomplete; `10` ABP death states | +| Runtime | RE-2A1-006 — IsDead false at spawn | +| Runtime | RE-2A1-004/013 — legacy health 0 at spawn (death-threshold risk if AnyDamage fires) | +| Runtime | RE-2A1-022 — death/respawn not observed | + +### Proposed rule + +- Death is evaluated from **canonical ASC Health**. +- Health ≤ 0 is evaluated **authoritatively on the server**. +- Death transition is **idempotent** — a player or enemy cannot execute the death transition twice. +- Dead state is **replicated**. +- Movement, abilities, collision, animation, and interaction respond to **one shared death state**. +- Animation does **not** own the authoritative death decision. + +**Player vs enemy separation:** same Health≤0 evaluation and idempotent dead state; players proceed to C-008 respawn; enemies proceed to destroy/loot/presentation policy (Phase 2D) without player respawn. + +### Allowed behavior + +- Server sets replicated dead state once; cancels abilities; disables input/movement as configured. +- ABP reads replicated dead state for Death animation only. + +### Prohibited behavior + +- AnimBP forcing alive over authoritative dead state. +- Death decided solely from DEPRECATED health after cutover. +- Re-entrant PlayerDeath without guard. + +### Transitional behavior + +Until Amazonian AnyDamage is migrated, treat legacy≤0 as transitional trigger that must also drive ASC Health to 0 / call the shared death entry — not a second SoT. + +### Dependencies + +C-001, C-005, C-008 (players), C-011 (ability cancel on death). + +### Migration impact + +Amazonian AnyDamage, PlayerDeath, enemy death ABP, future tags (`State.Dead`). + +### Runtime validation required + +- Damage to ASC 0 triggers death once; second damage does not re-enter. +- ABP plays death from replicated state. +- **Blocked today:** RT-006 (RE-2A1-022). + +### Failure modes + +- Legacy health 0 at spawn + AnyDamage → instant death while Overlay shows 75. +- Enemy ABP clears IsDead → corpse walks. + +### Approval question + +**Do you approve authoritative, idempotent death evaluated from ASC Health ≤ 0, with animation as presentation-only and player/enemy differing only in post-death lifecycle?** + +--- + +# C-008 — Respawn contract + +**State:** Proposed + +### Problem being solved + +Respawn/HUD recreation paths exist but are unverified. Risk of dying pawn owning its replacement, duplicate overlays, stale widgets, and skipped ASC re-init. + +### Current implementation + +- `Server_RespawnPlayer` / `PlayerRespawn` SpawnActor+Possess paths on base / PC / GM. +- Overlay created from `InitAbilityActorInfo` when local HUD present. +- Char-select `PlayerFirstSpawn` emits Accessed None warning but still spawns (RE-2A1-010). + +### Confirmed evidence + +| Kind | Evidence | +|---|---| +| Static | Docs `07` S8; `11` spawn/respawn; `03` PC_Character | +| Runtime | RE-2A1-010 — PlayerFirstSpawn Accessed None; spawn still succeeds | +| Runtime | RE-2A1-022 — respawn not observed (RT-006 blocked) | + +### Proposed rule + +- **GameMode and PlayerController** own the server-side respawn request and timing. The destroyed/dying pawn must **not** be the sole authority that initiates its replacement. +- Ordering: mark dead → cancel abilities (C-011) → schedule respawn delay → destroy or detach old pawn → spawn replacement → **re-Init ASC OwnerActor/AvatarActor** → reapply character defaults (C-002) → Possess → restore input → **idempotent HUD bind** (C-013). +- PlayerState persists across pawn replacement. +- Duplicate-respawn prevention: ignore respawn requests while already pending or while not dead. + +### Allowed behavior + +- Server GM/PC timer-driven respawn. +- Reuse PlayerState ASC; refresh Avatar to new pawn. + +### Prohibited behavior + +- Client-authoritative respawn. +- Multiple concurrent respawn schedules for one player. +- Skipping default attribute reapplication. + +### Transitional behavior + +Existing `Server_RespawnPlayer` on the pawn may forward a request to PC/GM but must not unilaterally complete the lifecycle without GM/PC ownership. + +### Dependencies + +C-002, C-007, C-012, C-013. + +### Migration impact + +`BP_PlayerCharacterBase` death/respawn, `PC_Character`, `GM_Dungeoneer`, HUD InitOverlay. + +### Runtime validation required + +- One death → one respawn; ASC defaults restored; Overlay instance count stable; input restored. +- **Blocked today:** RE-2A1-022. + +### Failure modes + +- Double Overlay; stale widget bound to destroyed pawn; ASC Avatar still old pawn; spawn warning becomes hard failure. + +### Approval question + +**Do you approve GameMode + PlayerController ownership of server respawn lifecycle (pawn must not solely replace itself), including ASC re-init, default reapplication, possession, input restore, and idempotent HUD bind?** + +--- + +# C-009 — Authority contract + +**State:** Proposed + +### Problem being solved + +Legacy gameplay timing depends on Multicast montage AnimNotify evaluation. Interrupt and server/client notify roles are unverified. Clients must submit intent only. + +### Current implementation + +``` +Input → Server_Ability_* → Multicast_PlayMontage → AnimNotify → UseAbility* (Authority gate) / SetIsAttacking +``` + +Montage OnCompleted/OnBlendOut/OnInterrupted pins unwired. Cleanup often via `AN_AttackComplete`. + +### Confirmed evidence + +| Kind | Evidence | +|---|---| +| Static | Docs `05`, `10` — notify-driven gameplay; Authority Switch inside UseAbility*; Networking Risk | +| Runtime | RE-2A1-015/019/021 — ability chain not executed (Enhanced Input Tool Limitation) | +| Runtime | RE-2A1-023–026 — two-client replication not run | + +### Proposed rule + +- Clients submit **intent**. +- Server validates state, target, resource cost, cooldown, and gameplay result. +- Multicast events are **presentation-only** unless a narrowly documented exception is later approved. +- Client or multicast animation evaluation **cannot be the sole authority** for damage, healing, spawning, costs, or state transitions. +- Replicated state is written only by its authoritative owner. + +### Allowed behavior + +- Server RPC intent → server commit → replicate state → multicast montage/SFX/VFX. +- Server-owned timing windows that *correlate* with animation (C-010) without requiring notify-as-authority. + +### Prohibited behavior + +- Gameplay results that only occur if a multicast notify runs. +- Client writing Health/Mana/IsDead/CurrentlyAttacking as authority. + +### Transitional behavior + +Legacy notify→UseAbility Authority bodies may remain temporarily but must be treated as **technical debt**. Migration moves hit commit to server Ability Tasks / validated windows. Document each remaining notify gameplay call site. + +### Dependencies + +C-003, C-005, C-006, C-010, C-011. + +### Migration impact + +All Server_Ability / Multicast_PlayMontage / AN_Ability_* paths; Phase 2B framework. + +### Runtime validation required + +- Listen-server + client: damage once on server; montage on both; no client-only Health change. +- **Blocked today:** Enhanced Input + multi-client PIE (RE-2A1-015, 023). + +### Failure modes + +- Server skips montage evaluation → missed hits under legacy design. +- Interrupt skips AN_AttackComplete → stuck CurrentlyAttacking. + +### Approval question + +**Do you approve client-intent / server-validation authority, with multicast limited to presentation, and AnimNotify forbidden as sole authority for damage, costs, or state transitions?** + +--- + +# C-010 — Animation responsibility contract + +**State:** Proposed + +### Problem being solved + +Animation currently gates hit windows and attack lockout cleanup. Need a clear cosmetic vs authoritative split while preserving timing feel. + +### Current implementation + +AN_Ability_* triggers UseAbility*; AN_AttackComplete clears CurrentlyAttacking; ABPs read IsDead/IsBlocking/etc. for presentation. + +### Confirmed evidence + +| Kind | Evidence | +|---|---| +| Static | Doc `10` shared animation→ability architecture | +| Runtime | Notify chain not exercised (RE-2A1-019/021) | + +### Proposed rule + +**Animation may own:** + +- Visual playback +- Sound timing +- Cosmetic Niagara timing +- Camera presentation +- Cosmetic weapon-trail windows + +**Animation may not solely own:** + +- Authoritative damage +- Cost commitment +- Target validation +- Death +- Respawn +- Guaranteed ability cleanup + +**Timing correlation:** Server (or server Ability Task) may open/close validated hit windows using durations/sections that match montage timing. Cosmetic notifies may fire predicted VFX. Authoritative commit remains server-side even if a notify is skipped. + +### Allowed behavior + +- Montage playback from server-triggered multicast. +- Cosmetic notifies. +- Server tasks waiting on montage events as *hints* with failsafe timeouts (C-011). + +### Prohibited behavior + +- Sole reliance on AN_AttackComplete for cleanup. +- Damage that only applies inside a multicast notify without prior/server validation path. + +### Transitional behavior + +Existing notify gameplay remains until Phase 2B replaces it under C-009/C-011. + +### Dependencies + +C-009, C-011, C-007. + +### Migration impact + +AN_Ability_001–004, AN_AttackComplete, Multicast_PlayMontage pins, character ABPs. + +### Runtime validation required + +- Interrupt mid-montage still cleans ability state without AN_AttackComplete. +- **Blocked today:** RE-2A1-020. + +### Failure modes + +- Cosmetic-only migration that still requires notify for damage. +- Desynced VFX vs server hit window (acceptable if documented; damage must still be correct). + +### Approval question + +**Do you approve animation as cosmetic-only for authority purposes, with server-owned timing correlation allowed, and notify-driven authoritative gameplay prohibited as the end state?** + +--- + +# C-011 — Ability lifecycle and cleanup contract + +**State:** Proposed + +### Problem being solved + +Most Server_Ability_*_End bodies are empty. Cleanup depends on AN_AttackComplete. Interrupt may leave CurrentlyAttacking stuck. + +### Current implementation + +Gates on CurrentlyAttacking/IsDead; Ends mostly empty; AN_AttackComplete clears attacking; montage interrupt pins unwired. + +### Confirmed evidence + +| Kind | Evidence | +|---|---| +| Static | Docs `05`, `07` S3/S12, `10` | +| Runtime | RE-2A1-020 — interrupt test blocked | + +### Proposed rule + +Shared lifecycle states: + +`Requested → Validated → Committed → Active → Ending → Completed | Canceled | Interrupted | Failed` + +| Event | Required behavior | +|---|---| +| Resource commitment | On Validated→Committed; atomic (C-003) | +| Cooldown commitment | On Commit (when cooldowns exist) | +| Montage start failure | → Failed; release commit if policy requires; clear attacking | +| Normal completion | → Completed; clear locks; EndAbility equivalent | +| Input release | Route to Ending/Canceled per ability policy | +| Interruption | → Interrupted; **guaranteed** cleanup without AN_AttackComplete | +| Death during ability | Cancel → Interrupted/Canceled; C-007 | +| Pawn destruction | Force cleanup; no dangling timers | +| Target invalidation | End or fail per ability; no further damage commits | +| Timeout / failsafe | Absolute cleanup timer independent of montage | + +**No ability may depend solely on AN_AttackComplete for guaranteed state cleanup.** + +### Allowed behavior + +- Explicit EndAbility / cancel tags / Ability Task end states. +- Failsafe timers. + +### Prohibited behavior + +- Cleanup only via montage end notify. +- Leaving CurrentlyAttacking true after interrupt/death. + +### Transitional behavior + +Wire montage OnInterrupted/OnBlendOut **or** native failsafe while notifies remain. + +### Dependencies + +C-003, C-007, C-008, C-009, C-010. + +### Migration impact + +All playable ability Begin/End/UseAbility paths; Phase 2B shared framework. + +### Runtime validation required + +- Full montage: lockout clears. +- Interrupt: lockout clears without AN_AttackComplete. +- Death mid-ability: cleanup + no further damage. +- **Blocked today:** RE-2A1-019–022. + +### Failure modes + +- Stuck attack lockout; orphan timers; double cost on retry. + +### Approval question + +**Do you approve the shared ability lifecycle states and the rule that cleanup must be guaranteed without sole dependence on AN_AttackComplete?** + +--- + +# C-012 — PlayerState and pawn ownership contract + +**State:** Proposed + +### Problem being solved + +Need clear persistent vs transient ownership across respawn. Enemy ASC ownership differs and GetASC via PlayerState returns nullptr for enemies. + +### Current implementation + +- Players: ASC + AttributeSet on `ARIRPlayerState`; InitAbilityActorInfo Owner=PS, Avatar=Character on PossessedBy / OnRep_PlayerState. +- Enemies: ASC on self; InitAbilityActorInfo(this,this); interface GetASC → PlayerState → nullptr. + +### Confirmed evidence + +| Kind | Evidence | +|---|---| +| Static | Doc `06` ownership detail; `09` enemy GetASC defect | +| Runtime | RE-2A1-007 — PS ASC; pawn query resolves same set | +| Runtime | RE-2A1-027/028 — enemy ASC components present; inspector rejects actor (Tool Limitation / possible init gap) | + +### Proposed rule + +**PlayerState owns:** + +- Persistent player ASC +- Persistent AttributeSet +- Cross-pawn player state intended to survive respawn + +**Pawn owns:** + +- Avatar representation +- Movement +- Equipment components +- Transient physical state +- Animation +- Pawn-specific targeting and presentation + +**On possession / pawn replacement:** re-InitAbilityActorInfo; bind Overlay if local; teardown transient pawn state on old pawn. **Enemies** keep self-owned ASC with a separate init/accessor contract (fix GetASC for non-PlayerState owners in Phase 2D/2E). + +### Allowed behavior + +- Cache ASC pointer on pawn from PlayerState. +- Persistent attributes survive pawn destroy. + +### Prohibited behavior + +- Moving player ASC to pawn without an approved redesign. +- Expecting enemy GetASC-via-PlayerState to succeed. + +### Transitional behavior + +Keep current player PS ownership. Document enemy accessor as Existing Baseline Defect until fixed under this contract’s enemy clause. + +### Dependencies + +C-002, C-008, C-013. + +### Migration impact + +`ARIRPlayerCharacter`, `ARIRPlayerState`, enemy GetASC, EffectActor targeting. + +### Runtime validation required + +- After respawn: OwnerActor still PlayerState; Avatar is new pawn; attributes persist then defaults reapplied per C-002. +- Enemy ASC readable via corrected accessor (deferred). +- Tool inaccessibility ≠ runtime absence (RE-2A1-028). + +### Failure modes + +- Avatar not updated → abilities target wrong actor. +- Enemy potions destroy without apply (nullptr ASC). + +### Approval question + +**Do you approve keeping player ASC/AttributeSet on PlayerState with pawn as Avatar only, and treating enemy self-ASC as a separate ownership/init contract?** + +--- + +# C-013 — HUD data-flow contract + +**State:** Proposed + +### Problem being solved + +Dual HUD paths: Overlay (ASC) works structurally; legacy `UpdatePlayerHUD` unimplemented. Respawn may recreate overlays. Stamina UI missing. + +### Current implementation + +- `ARIRHUD::InitOverlay` → OverlayWidgetController → Health/Mana bars. +- `Server_UpdateHUD` → `UpdatePlayerHUD` unimplemented on PC. +- No stamina widget. + +### Confirmed evidence + +| Kind | Evidence | +|---|---| +| Static | Docs `11`, `06`, `07` S10 | +| Runtime | RE-2A1-008/009 — Overlay bars present; WBP_PlayerHUD spawned; no stamina widget | +| Runtime | Respawn Overlay duplication not observed (RT-006 blocked) | + +### Proposed rule + +- Gameplay HUD reads ASC attributes through the Overlay / widget-controller path. +- Legacy `UpdatePlayerHUD` route is **retired** (remove or leave dead; do not implement as second SoT). +- No UI independently stores authoritative resources. +- HUD creation is **idempotent**. +- Respawn and travel must not create duplicate overlays. +- Stamina presentation is added **only after** C-001/C-002 are approved. +- UI reflects replicated authoritative state and does **not** drive gameplay state. + +### Allowed behavior + +- Rebind existing Overlay to new pawn/ASC avatar on respawn. +- Progress bars from attribute delegates. + +### Prohibited behavior + +- Implementing UpdatePlayerHUD as a parallel authoritative HUD. +- UI writing Health/Mana. +- Unconditional InitOverlay without duplicate guard. + +### Transitional behavior + +Leave unimplemented UpdatePlayerHUD as dead code until removal; do not repair it. + +### Dependencies + +C-001, C-002, C-008, C-012. + +### Migration impact + +`RIRHUD`, Overlay widgets, BPI_PlayerController UpdatePlayerHUD, Server_UpdateHUD callers. + +### Runtime validation required + +- One Overlay after spawn and after respawn. +- Bars track ASC only. +- **Blocked:** respawn path (RE-2A1-022). + +### Failure modes + +- Duplicate overlays; stale bar bound to destroyed pawn; stamina UI before SoT approval. + +### Approval question + +**Do you approve Overlay/widget-controller as the sole gameplay HUD data path, retirement of UpdatePlayerHUD, idempotent HUD creation, and deferred stamina UI until attribute contracts are approved?** + +--- + +# C-014 — Pickup authority and replication contract + +**State:** Proposed + +### Problem being solved + +EffectActor pickups have no authority gate and `bReplicates=false`, risking desync and duplicate apply. Overlap apply not runtime-proven. + +### Current implementation + +Overlap → ApplyEffectToTarget → DestroyActor; no SwitchHasAuthority; bReplicates=false; destroy even if ASC null. + +### Confirmed evidence + +| Kind | Evidence | +|---|---| +| Static | Doc `12` Authority Risk matrix | +| Runtime | RE-2A1-017 — HealthPotion `bReplicates=false` | +| Runtime | RE-2A1-016 — pickups present in Test01 | +| Runtime | RE-2A1-018 — overlap/GE apply not executed | + +### Proposed rule + +- Server owns overlap validation. +- Server applies the effect or mutation. +- Server destroys or deactivates the pickup. +- All clients receive a **consistent pickup-existence** state. +- A pickup applies **at most once** per valid collection. +- Cosmetic presentation may occur on clients **after** authoritative collection. +- Non-replicated pickups must **not** be used for network gameplay without an explicit server-owned spawning/visibility model. + +### Allowed behavior + +- Replicated pickup actors; server authority gate; server GE apply; server destroy. +- SP prototype with documented non-replicated model only if never used in MP as-is. + +### Prohibited behavior + +- Client-only destroy/apply for MP pickups. +- Relying on `bReplicates=false` EffectActors for listen-server gameplay. + +### Transitional behavior + +SP Test01 may keep current actors until 2E reconstruction, but they are classified Authority Risk and must not be treated as MP-correct. + +### Dependencies + +C-003, C-006, C-012 (GetASC for enemies). + +### Migration impact + +Four EffectActor pickups; gold path (separate AddGold defect); Phase 2E. + +### Runtime validation required + +- Server apply once; ASC changes; actor gone on all clients. +- **Blocked today:** movement/input and 2P (RE-2A1-018, 023, 026). + +### Failure modes + +- Double GE apply; client destroy without server apply; enemy touch destroys without heal. + +### Approval question + +**Do you approve server-owned pickup validation/apply/destroy with replicated existence, at-most-once collection, and a ban on non-replicated pickups for network gameplay without an explicit server visibility model?** + +--- + +# C-015 — Runtime observability contract + +**State:** Proposed + +### Problem being solved + +Reconstruction needs inspectable evidence. Phase 2A1 showed tool gaps (Enhanced Input, multi-client, enemy ASC inspector). Observability must be defined without requiring permanent debug UI yet. + +### Current implementation + +Ad-hoc MCP/ObjectTools/AbilitySystemInspector during Phase 2A1; no project harness. + +### Confirmed evidence + +| Kind | Evidence | +|---|---| +| Runtime | Tool limitations RE-2A1-015, 023, 028, 031 | +| Inference | Without logs/harness, C-005–C-011/C-014 cannot close | + +### Proposed rule + +Before reconstruction claims are trusted, the following must be inspectable via logs, debugger, Ability System inspection, or a future temporary test harness: + +- Character identity +- ASC OwnerActor and AvatarActor +- Current/max attributes +- Active Gameplay Effects +- Granted abilities +- Ability lifecycle state +- Authoritative damage events +- Death transitions +- Respawn transitions +- Pickup application count +- Network role + +Permanent debug UI is **not** required yet. + +### Allowed behavior + +- Structured log categories; temporary console/cheats in development builds; automation hooks. + +### Prohibited behavior + +- Treating tool inaccessibility as proof of runtime absence. +- Shipping permanent debug HUD as a substitute for contracts. + +### Transitional behavior + +Use manual PIE + logging until harness exists; environment decisions for 2-client PIE and Enhanced Input remain open (see `02`). + +### Dependencies + +All contracts for validation; harness work may be Phase 2A3 planning. + +### Migration impact + +Logging helpers; future test harness; no gameplay SoT change. + +### Runtime validation required + +- Each listed field obtainable in a controlled session for player pawn; enemy attributes once accessor fixed. + +### Failure modes + +- False “missing ASC” from inspector limits; unverifiable MP claims. + +### Approval question + +**Do you approve the minimum observability list above as a prerequisite for trusting reconstruction, without requiring permanent debug UI yet?** + +--- + +# Architectural recommendation summary + +## 1. Recommended canonical architecture + +ASC attributes on PlayerState are the sole resource SoT. Character default GEs initialize explicit current+max H/M/S on the server after actor info is valid. All gameplay resource mutation flows through a shared server interface. Damage and healing write ASC through one authoritative boundary. Death evaluates ASC Health ≤ 0 idempotently. GameMode/PC own respawn. HUD reads Overlay/ASC only. Abilities use client intent → server validate → presentation multicast, with server-owned lifecycle/cleanup. Enemies and pickups consume the same damage/resource rules under later phases. + +## 2. Transitional architecture + +- ASC→legacy one-way shadow for unconverted read-only consumers. +- ApplyDamage adapter into ASC damage boundary. +- Notify-timed UseAbility retained as debt until Ability Tasks / validated windows. +- SP non-replicated pickups tolerated only as known Authority Risk until 2E. + +## 3. Prohibited transitional patterns + +- Bidirectional ASC↔legacy sync +- Legacy writers silently overwriting ASC +- Multicast AnimNotify as sole gameplay authority +- Silent native Init* fallback hiding missing character defaults +- Non-replicated pickups used as-is for network gameplay +- Implementing UpdatePlayerHUD as a second resource SoT +- Treating tool limitation as runtime absence + +## 4. Decisions requiring owner approval + +All C-001 through C-015 approval questions above. None are Approved in this pass. + +## 5. Decisions blocked by runtime evidence + +| Area | Blocking evidence | Related contracts | +|---|---|---| +| Enhanced Input ability execution | RE-2A1-015/019/021 | C-009, C-010, C-011 | +| AnimNotify authority roles | Not observed | C-009, C-010 | +| Ability cost mutation | Not observed; Ability004 cost CDO=0 | C-003, C-004 | +| Ability interruption | RE-2A1-020 | C-011 | +| Player damage/death/respawn | RE-2A1-022 | C-005, C-007, C-008 | +| Two-client replication | RE-2A1-023–026 | C-009, C-014 | +| Remote character selection | Not run (needs 2P) | C-008 related / 2E | +| Pickup authority and visibility | RE-2A1-018 | C-014 | +| Enemy attribute mutation | RE-2A1-028/030 | C-005, C-012 | +| Session behavior | Deferred to 2E; not in 2A1 matrices | Outside 2A2a contracts | + +## 6. Phase 2A3 implementation-planning prerequisites + +1. Owner review of Proposed contracts (still no Approved stamp until explicitly granted). +2. Plan for remaining blocked runtime evidence (input harness, 2-client PIE authorization, controlled damage actor if approved). +3. Migration sequencing: C-001/C-002/C-003/C-004 → C-005/C-006/C-007 → C-008/C-013 → C-009–C-011 → C-014 with 2E. +4. Observability harness outline per C-015. +5. Explicit non-goals: no Phase 2B ability rewrite; no Unreal edits in 2A2a. + +## Dependency diagram + +```mermaid +flowchart TD + attrs[CanonicalAttributes_C001_C002] + resource[SharedResourceBoundary_C003_C004] + dmgHeal[DamageHealing_C005_C006] + death[Death_C007] + respawn[Respawn_C008] + hud[HUD_C013] + ability[AbilityLifecycle_C009_C010_C011] + migrate[CharacterMigration] + enemy[EnemyReconstruction] + pickups[Pickups_C014] + observe[Observability_C015] + attrs --> resource + resource --> dmgHeal + dmgHeal --> death + death --> respawn + resource --> hud + respawn --> hud + resource --> ability + ability --> migrate + dmgHeal --> enemy + death --> enemy + resource --> pickups + observe -.-> attrs + observe -.-> dmgHeal + observe -.-> ability + observe -.-> pickups +``` + +## Integrity statement + +This document is Markdown-only architecture design. No Unreal assets, source, configuration, plugins, or maps were modified. No Unreal MCP or PIE was used in Phase 2A2a. No contract is Approved. diff --git a/Documentation/Phase2/04-Phase2A-DecisionRegister.md b/Documentation/Phase2/04-Phase2A-DecisionRegister.md new file mode 100644 index 00000000..5432a712 --- /dev/null +++ b/Documentation/Phase2/04-Phase2A-DecisionRegister.md @@ -0,0 +1,342 @@ +# Phase 2A — Decision Register + +| Field | Value | +|---|---| +| Status | Draft | +| Date | 2026-07-17 | +| Phase | 2A2a | +| Starting Git commit | `9919faab` | +| Rule | All entries are **Proposed**, **Alternative**, **Deferred**, or **Blocked**. None are **Approved**. | + +Companion: [`03-SharedGameplayContracts.md`](03-SharedGameplayContracts.md). Open-decision reconciliation: [`02-Phase2A-OpenDecisions.md`](02-Phase2A-OpenDecisions.md). + +--- + +## Summary table + +| Decision | Recommendation | Confidence | Blocking issue | Approval required | +|---|---|---|---|---| +| C-001 | ASC AttributeSet sole SoT for H/M/S currents and maxes | High | None for proposal; combat cutover needs death PIE later | Yes | +| C-002 | Option A — character-specific default GE after ASC actor info valid | Medium | Orphan GEs lack Max*; must fail visibly if missing | Yes | +| C-003 | Shared server ASC resource interface; atomic costs | High | Cost mutation path not runtime-proven | Yes | +| C-004 | ASC→legacy one-way shadow only; bidirectional rejected | High | Which consumers still need shadow until migrated | Yes | +| C-005 | Server damage boundary writing ASC; ApplyDamage as adapter; ExecCalc deferred | Medium | Damage/death path not exercised (RE-2A1-022) | Yes | +| C-006 | Server restore via same boundary; clamp to Max*; no over-resource by default | Medium | Pickup/heal overlap not observed (RE-2A1-018) | Yes | +| C-007 | Death from ASC Health ≤ 0; idempotent; anim presentation-only | Medium | Death path not observed; legacy health 0 at spawn risk | Yes | +| C-008 | GameMode + PC own respawn; ASC re-init; idempotent HUD | Medium | Respawn not observed (RE-2A1-022) | Yes | +| C-009 | Client intent; server validate; multicast presentation-only | Medium | Ability + 2P paths blocked (RE-2A1-015, 023) | Yes | +| C-010 | Animation cosmetic; server timing correlation; no notify authority | Medium | Notify chain not executed | Yes | +| C-011 | Shared lifecycle; guaranteed cleanup without sole AN_AttackComplete | Medium | Interrupt test blocked (RE-2A1-020) | Yes | +| C-012 | Player ASC on PlayerState; pawn Avatar; enemy self-ASC separate | High | Enemy inspector Tool Limitation (RE-2A1-028) | Yes | +| C-013 | Overlay-only HUD; retire UpdatePlayerHUD; defer stamina UI | High | Respawn Overlay duplication untested | Yes | +| C-014 | Server pickup validate/apply/destroy; replicate existence; ban naked non-rep MP pickups | Medium | Overlap apply + 2P blocked | Yes | +| C-015 | Minimum observability list; no permanent debug UI required yet | Medium | Harness not built; env limits remain | Yes | + +--- + +## C-001 — Canonical player resource source of truth + +| Field | Content | +|---|---| +| Decision ID | C-001 | +| Title | Canonical player resource source of truth | +| State | Proposed | +| Recommended option | ASC attributes are sole SoT for Health, MaxHealth, Mana, MaxMana, Stamina, MaxStamina; DEPRECATED vars non-authoritative | +| Alternatives | Keep legacy SoT during reconstruction only (rejected as primary); character-specific transitional dual-SoT (rejected — prolongs P0) | +| Static evidence | `05-LegacyAbilityArchitecture.md` resource inventory; `06-PartialGASArchitecture.md` §8 legacy/GAS boundary; `01-ExecutiveSummary.md` P0 dual resources | +| Runtime evidence | RE-2A1-001, 004, 005, 012, 013; RT-001, RT-002 | +| Benefits | One truth for UI, combat, potions, death; removes spawn divergence class of bugs | +| Risks | Breaking unconverted legacy readers if shadow/cutover incomplete | +| Migration impact | Abilities, Amazonian death, Cleric heal, HUD, future stamina | +| Blocking unknowns | Whether AnyDamage fires with legacy health already 0 | +| Runtime validation | Post-init ASC match; potion vs combat both mutate ASC; death from ASC | +| Approval question | Do you approve ASC AttributeSet as the sole canonical source of truth for Health, MaxHealth, Mana, MaxMana, Stamina, and MaxStamina, with DEPRECATED Blueprint resource variables treated as non-authoritative? | + +--- + +## C-002 — Character default attribute initialization + +| Field | Content | +|---|---| +| Decision ID | C-002 | +| Title | Character default attribute initialization | +| State | Proposed | +| Recommended option | A — Character-specific default Gameplay Effect selected by pawn/class; server apply after ASC actor info valid; explicit current+max H/M/S; visible fail on missing assignment | +| Alternatives | B — Shared init GE + SetByCaller; C — Native initialization service; hybrid Max* fill transitional | +| Static evidence | `06-PartialGASArchitecture.md` §§2–4 default GE matrix; native Init*; DefaultAttributesGameplayEffect=None | +| Runtime evidence | RE-2A1-001, 002, 011, 012 — identical ASC; no active GE; CDO legacy defaults | +| Benefits | Per-class balance; reuses existing GE assets/property; deterministic spawn/respawn | +| Risks | Existing orphan GEs omit Max*; incomplete GE applied → broken clamps | +| Migration impact | PlayerState, character GEs, Gunslinger missing GE, spawn/respawn | +| Blocking unknowns | Final per-class balance numbers (design); Gunslinger defaults | +| Runtime validation | Per-class ASC after spawn/respawn; missing assignment visible error | +| Approval question | Do you approve Option A (character-specific default Gameplay Effect applied server-side after ASC actor info is valid), with visible failure on missing assignment and mandatory explicit current+max Health/Mana/Stamina? | + +--- + +## C-003 — Resource-access boundary + +| Field | Content | +|---|---| +| Decision ID | C-003 | +| Title | Resource-access boundary | +| State | Proposed | +| Recommended option | Shared authoritative ASC interface; atomic server cost check+mutate; no new DEPRECATED direct access | +| Alternatives | Per-system ad-hoc ASC reads (rejected — recreates dual writers) | +| Static evidence | `05` FCanUseMana / DEPRECATED costs; `07` S9; `06` boundary | +| Runtime evidence | RE-2A1-014, 015 — cost path not proven; Ability004ManaCost CDO=0 | +| Benefits | Incremental migration without two SoTs; consistent affordability | +| Risks | Bypass of interface during hasty BP edits | +| Migration impact | All cost/heal/damage resource call sites | +| Blocking unknowns | Exact FCanUseMana body edge cases; cost timing vs montage | +| Runtime validation | Cost reduces ASC once; failed affordability no mutation | +| Approval question | Do you approve a shared server-authoritative ASC resource interface as the only allowed read/write path for new gameplay resource access, with atomic cost validation and mutation? | + +--- + +## C-004 — Legacy compatibility policy + +| Field | Content | +|---|---| +| Decision ID | C-004 | +| Title | Legacy compatibility policy | +| State | Proposed | +| Recommended option | C — ASC→legacy one-way shadow for temporary read-only consumers; prefer D cutover when possible | +| Alternatives | D — No sync / migrate first; A bidirectional **Rejected by Existing Evidence**; B legacy→ASC rejected as primary | +| Static evidence | `06` sync Missing; `01` P0 dual pools | +| Runtime evidence | RE-2A1-004, 005, 013 — divergent spawn; Overlay ASC vs combat legacy | +| Benefits | Avoids feedback loops; protects ASC from zeroed legacy writers | +| Risks | Shadow forgotten; legacy writer still active | +| Migration impact | AnyDamage, FCanUseMana readers, Server_UpdateHUD | +| Blocking unknowns | Full runtime inventory of legacy readers during death/ability | +| Runtime validation | Shadow matches after ASC change; legacy cannot overwrite ASC | +| Approval question | Do you approve ASC→legacy one-way shadow only for temporary read-only consumers, with bidirectional sync prohibited and legacy writers forbidden from silently overwriting ASC? | + +--- + +## C-005 — Damage contract + +| Field | Content | +|---|---| +| Decision ID | C-005 | +| Title | Damage contract | +| State | Proposed | +| Recommended option | Single server damage boundary writing ASC Health; legacy ApplyDamage as transitional adapter; ExecutionCalculation deferred | +| Alternatives | Pure GE ExecutionCalculation (Deferred/Alternative); keep ApplyDamage+legacy health (Rejected as end state) | +| Static evidence | `05` ApplyDamage paths; `09` enemy reception Missing; `06` no ExecCalc project subclasses | +| Runtime evidence | RE-2A1-022, 027, 030 — damage not observed; enemy components present | +| Benefits | One entry for players/enemies; dedupe; death hook | +| Risks | Adapter gap during migration; enemy consumer still Missing | +| Migration impact | All ApplyDamage sites; Amazonian AnyDamage; Phase 2D enemies | +| Blocking unknowns | Runtime authority of hit windows; block absorb design | +| Runtime validation | Single ASC Health reduction; no double hit; death trigger | +| Approval question | Do you approve a single server-authoritative damage entry that writes ASC Health, with legacy ApplyDamage limited to a transitional adapter, and ExecutionCalculation design deferred? | + +--- + +## C-006 — Healing and resource restoration contract + +| Field | Content | +|---|---| +| Decision ID | C-006 | +| Title | Healing and resource restoration contract | +| State | Proposed | +| Recommended option | Server restore via shared ASC boundary; clamp to Max*; consumables same path; no over-resource by default | +| Alternatives | Allow overheal via tagged GEs only (future design) | +| Static evidence | `05` Cleric recover; `06`/`12` potion GEs; no AttributeSet clamp | +| Runtime evidence | RE-2A1-018 — pickup apply not run | +| Benefits | Overlay and combat agree; potions/abilities consistent | +| Risks | Cleric transitional dual heal if not adapted | +| Migration impact | Cleric 002, EffectActors, DEPRECATED recover | +| Blocking unknowns | Intended overheal design (none evidenced) | +| Runtime validation | Clamp at max; potion +25 once; Overlay update | +| Approval question | Do you approve server-authoritative restoration through the shared ASC resource boundary, clamping to Max* by default, with consumables and ability heals using the same path? | + +--- + +## C-007 — Death contract + +| Field | Content | +|---|---| +| Decision ID | C-007 | +| Title | Death contract | +| State | Proposed | +| Recommended option | Authoritative idempotent death from ASC Health ≤ 0; shared replicated dead state; anim presentation-only | +| Alternatives | Tag-only State.Dead as primary (Deferred until tags wired); legacy≤0 SoT (Rejected as end state) | +| Static evidence | `05` Amazonian death; `09` enemy IsDead forced false; `10` ABP Death | +| Runtime evidence | RE-2A1-006, 004, 013, 022 — IsDead false; legacy health 0; death not observed | +| Benefits | Idempotent; aligns Overlay and death; fixes enemy ABP ownership of truth | +| Risks | Instant death if legacy path fires before ASC cutover | +| Migration impact | PlayerDeath, Amazonian AnyDamage, enemy death ABP, tags | +| Blocking unknowns | Whether AnyDamage runs at legacy 0; Paladin inbound damage path | +| Runtime validation | One death transition; no re-entry; ABP follows replicated state | +| Approval question | Do you approve authoritative, idempotent death evaluated from ASC Health ≤ 0, with animation as presentation-only and player/enemy differing only in post-death lifecycle? | + +--- + +## C-008 — Respawn contract + +| Field | Content | +|---|---| +| Decision ID | C-008 | +| Title | Respawn contract | +| State | Proposed | +| Recommended option | GameMode + PlayerController own server respawn lifecycle; pawn does not solely replace itself | +| Alternatives | Pawn-owned Server_RespawnPlayer as sole owner (Rejected as primary) | +| Static evidence | `07` S8; `11` PlayerRespawn / PlayerFirstSpawn | +| Runtime evidence | RE-2A1-010 — spawn warning; RE-2A1-022 — respawn untested | +| Benefits | Clear ownership; ASC/HUD rebind; duplicate-respawn guard | +| Risks | Existing pawn respawn graphs need rewiring; PlayerFirstSpawn warning | +| Migration impact | GM_Dungeoneer, PC_Character, base death/respawn, HUD | +| Blocking unknowns | Exact timer (~2s) intent; Overlay recreate vs rebind preference in practice | +| Runtime validation | One respawn; ASC Owner/Avatar correct; defaults reapplied; one Overlay | +| Approval question | Do you approve GameMode + PlayerController ownership of server respawn lifecycle (pawn must not solely replace itself), including ASC re-init, default reapplication, possession, input restore, and idempotent HUD bind? | + +--- + +## C-009 — Authority contract + +| Field | Content | +|---|---| +| Decision ID | C-009 | +| Title | Authority contract | +| State | Proposed | +| Recommended option | Client intent → server validate/commit → multicast presentation-only; notify not sole authority | +| Alternatives | Allow Authority-gated notify gameplay indefinitely (Rejected as end state); documented narrow exceptions (Deferred) | +| Static evidence | `05`/`10` Input→Server→Multicast→AN→UseAbility | +| Runtime evidence | RE-2A1-015, 019, 021, 023–026 — ability/2P not observed | +| Benefits | Predictable MP; removes interrupt/notify authority risk | +| Risks | Timing feel change during migration; temporary dual patterns | +| Migration impact | All ability network paths; Phase 2B | +| Blocking unknowns | Server vs client notify evaluation roles at runtime | +| Runtime validation | Listen-server damage once; montage both; no client Health write | +| Approval question | Do you approve client-intent / server-validation authority, with multicast limited to presentation, and AnimNotify forbidden as sole authority for damage, costs, or state transitions? | + +--- + +## C-010 — Animation responsibility contract + +| Field | Content | +|---|---| +| Decision ID | C-010 | +| Title | Animation responsibility contract | +| State | Proposed | +| Recommended option | Animation owns cosmetics; may correlate timing; must not solely own damage/cost/death/respawn/cleanup | +| Alternatives | Keep notify-authoritative hit windows (Rejected as end state) | +| Static evidence | `10-AnimationDependencies.md` shared architecture and Networking Risk | +| Runtime evidence | RE-2A1-019–021 — notify path not run | +| Benefits | Clear cosmetic vs authority split; preserves timing via server windows | +| Risks | VFX desync vs hits; migration cost for montages | +| Migration impact | AN_Ability_*, AN_AttackComplete, Multicast_PlayMontage | +| Blocking unknowns | Exact notify trigger times (Manual Editor) | +| Runtime validation | Interrupt cleanup without AN_AttackComplete; hits still server-valid | +| Approval question | Do you approve animation as cosmetic-only for authority purposes, with server-owned timing correlation allowed, and notify-driven authoritative gameplay prohibited as the end state? | + +--- + +## C-011 — Ability lifecycle and cleanup contract + +| Field | Content | +|---|---| +| Decision ID | C-011 | +| Title | Ability lifecycle and cleanup contract | +| State | Proposed | +| Recommended option | Shared lifecycle states; guaranteed cleanup on interrupt/death/destroy/timeout; no sole AN_AttackComplete dependence | +| Alternatives | Montage blend-out notify required (insufficient alone); cancel tags + EndAbility (compatible Alternative) | +| Static evidence | `05` empty Ends; `07` S3/S12; `10` unwired montage pins | +| Runtime evidence | RE-2A1-020 — interrupt blocked | +| Benefits | No stuck CurrentlyAttacking; safe death mid-ability | +| Risks | Under-specified per-ability cancel policy | +| Migration impact | All Begin/End/UseAbility; Phase 2B framework | +| Blocking unknowns | Which existing actions can interrupt without asset edits | +| Runtime validation | Complete and interrupted montages both clear locks | +| Approval question | Do you approve the shared ability lifecycle states and the rule that cleanup must be guaranteed without sole dependence on AN_AttackComplete? | + +--- + +## C-012 — PlayerState and pawn ownership contract + +| Field | Content | +|---|---| +| Decision ID | C-012 | +| Title | PlayerState and pawn ownership contract | +| State | Proposed | +| Recommended option | Keep player ASC/AttributeSet on PlayerState; pawn Avatar; enemy self-ASC separate contract | +| Alternatives | Move ASC to pawn (Rejected unless redesign approved); dual ownership unclear Avatar rules (Rejected) | +| Static evidence | `06` ownership; `09` enemy GetASC nullptr | +| Runtime evidence | RE-2A1-007, 027, 028 | +| Benefits | Survives respawn; matches existing native design | +| Risks | Enemy accessor defect continues until 2D/2E fix | +| Migration impact | InitAbilityActorInfo, EffectActor GetASC, enemies | +| Blocking unknowns | Whether enemy InitAbilityActorInfo fully exposes ASC to inspector | +| Runtime validation | Post-respawn Owner/Avatar; enemy ASC via corrected accessor | +| Approval question | Do you approve keeping player ASC/AttributeSet on PlayerState with pawn as Avatar only, and treating enemy self-ASC as a separate ownership/init contract? | + +--- + +## C-013 — HUD data-flow contract + +| Field | Content | +|---|---| +| Decision ID | C-013 | +| Title | HUD data-flow contract | +| State | Proposed | +| Recommended option | Overlay/widget-controller only; retire UpdatePlayerHUD; idempotent HUD; defer stamina UI | +| Alternatives | Implement UpdatePlayerHUD as second path (Rejected); recreate Overlay every possess without guard (Rejected) | +| Static evidence | `11` HUD matrix; `07` S10 unimplemented UpdatePlayerHUD | +| Runtime evidence | RE-2A1-008, 009 — Overlay present; no stamina widget | +| Benefits | Single UI SoT; avoids duplicate overlays | +| Risks | Respawn rebind bugs if InitOverlay not idempotent | +| Migration impact | RIRHUD, Overlay, Server_UpdateHUD callers | +| Blocking unknowns | Exact Overlay instance counts after respawn | +| Runtime validation | One Overlay spawn+respawn; bars track ASC | +| Approval question | Do you approve Overlay/widget-controller as the sole gameplay HUD data path, retirement of UpdatePlayerHUD, idempotent HUD creation, and deferred stamina UI until attribute contracts are approved? | + +--- + +## C-014 — Pickup authority and replication contract + +| Field | Content | +|---|---| +| Decision ID | C-014 | +| Title | Pickup authority and replication contract | +| State | Proposed | +| Recommended option | Server validate/apply/destroy; replicated existence; at-most-once; ban non-rep MP pickups without server visibility model | +| Alternatives | Server RPC from client overlap (Alternative); SP-only non-rep prototypes documented (transitional only) | +| Static evidence | `12-Pickups-And-Effects.md` Authority Risk | +| Runtime evidence | RE-2A1-016, 017, 018 | +| Benefits | Consistent MP; prevents double apply | +| Risks | Requires actor replication enablement; enemy null ASC destroy side effect | +| Migration impact | Four EffectActors; Phase 2E; GetASC fix interaction | +| Blocking unknowns | Duplicate apply under 2P; sphere overlap details | +| Runtime validation | One apply; ASC change; destroyed on all clients | +| Approval question | Do you approve server-owned pickup validation/apply/destroy with replicated existence, at-most-once collection, and a ban on non-replicated pickups for network gameplay without an explicit server visibility model? | + +--- + +## C-015 — Runtime observability contract + +| Field | Content | +|---|---| +| Decision ID | C-015 | +| Title | Runtime observability contract | +| State | Proposed | +| Recommended option | Minimum inspectable set via logs/debugger/ASC inspect/future harness; no permanent debug UI required yet | +| Alternatives | Permanent debug HUD (Deferred); do nothing (Rejected — blocks reconstruction trust) | +| Static evidence | `13-Unknowns-And-RuntimeQuestions.md` runtime groups; `15` handoff | +| Runtime evidence | RE-2A1-015, 023, 028, 031 — tool/environment limits | +| Benefits | Makes blocked areas closable; prevents false negatives from tools | +| Risks | Harness scope creep; env still blocks Enhanced Input / 2P | +| Migration impact | Logging; temporary harness; not gameplay SoT | +| Blocking unknowns | How to enable 2-client PIE without config save; Enhanced Input injection | +| Runtime validation | Each listed field obtainable in controlled session | +| Approval question | Do you approve the minimum observability list as a prerequisite for trusting reconstruction, without requiring permanent debug UI yet? | + +--- + +## Register integrity + +- No decision recorded as Approved. +- Recommendations are Proposed only. +- Bidirectional sync recorded as Rejected by Existing Evidence under C-004. +- ExecutionCalculation under C-005 is Deferred / Alternative, not selected.