docs(runtime): close canonical action ownership

Record J5.1's exact Runtime selection, combat, and target-mode owner, its automated and connected acceptance evidence, rollback, and the J5.2 interaction-transaction boundary. Synchronize architecture, roadmap, milestones, issues, and agent handoff state.

Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-26 10:54:12 +02:00
parent b298f99f91
commit be73bccf5a
10 changed files with 206 additions and 17 deletions

View file

@ -0,0 +1,113 @@
# Slice J5.1 — canonical action state
**Date:** 2026-07-26
**Production commit:** `b298f99f913249d299796e6a71f7a9b6b283ac1a`
**Parent:** `docs/plans/2026-07-26-modern-runtime-slice-j5.md`
## Result
Selection identity, combat mode/known target health, and retail's temporary
Use/Examine/Use-Item-On-Target mode now form one presentation-independent
Runtime lifetime group.
`RuntimeActionState` constructs and owns the exact three mutable children.
`GameWindow` owns one Runtime action root, while Program/plugin selection,
retained UI, session routing, input/combat consumers, and current-runtime
commands/views borrow its exact children. No production App path can construct
another selection, combat, or interaction-mode owner.
The old `AcDream.App.UI.InteractionState` moved to
`AcDream.Runtime.Gameplay`. `ItemInteractionController` now requires the exact
injected state and has no private fallback.
## Retail behavior preserved
No selection, combat, or item-use algorithm changed.
- `SelectionState` retains
`ACCWeenieObject::SetSelectedObject @ 0x0058C2E0`: commit the changed
selection and previous identities before synchronous observers, and
deduplicate a same-object selection.
- `CombatState.Clear` retains
`ClientCombatSystem::Begin @ 0x0056A460`: session reset returns to
NonCombat and clears known target health.
- target-mode entry/acquisition/cancellation remains the existing
`ItemHolder::UseObject @ 0x00588A80` projection.
- commands remain synchronous at the existing press-time boundary; this slice
adds no queue or frame of latency.
## Ownership and failure behavior
- `RuntimeActionState.View` projects revisions plus selected/previous identity,
combat mode, known-health count/query, and interaction mode without copying
a mutable collection.
- reset attempts interaction, selection, and combat suffixes even when one
borrowed observer throws.
- terminal disposal is failure-safe: it clears all children, detaches Runtime's
internal revision subscriptions, and becomes terminal even when observers
fail.
- two Runtime action roots in one process remain completely isolated.
- `RuntimeGameplayOwnership` now includes the action root in its combined
convergence ledger.
- terminal App shutdown releases UI/session borrowers before disposing the
Runtime action root and then the canonical entity/object lifetime.
Production source guards scan all non-Studio App sources and prove that only
the Runtime owner constructs `SelectionState`, `CombatState`, or
`InteractionState`. Existing Runtime dependency and assembly-load closure
tests prove no App, UI, Silk.NET, OpenAL, Arch, or ImGui dependency entered the
kernel.
## Automated gates
All commands ran in Release:
- `dotnet test tests/AcDream.Runtime.Tests/AcDream.Runtime.Tests.csproj`:
182 passed.
- `dotnet test tests/AcDream.App.Tests/AcDream.App.Tests.csproj`:
3,779 passed / 3 fixture-generator skips.
- `dotnet build AcDream.slnx -c Release`: passed.
- `dotnet test AcDream.slnx -c Release --no-build --no-restore`:
8,550 passed / 5 established skips.
- `git diff --check`: passed.
## Exact-binary connected gate
Report:
`logs/connected-world-gate-20260726-104445/report.json`.
The report identifies exact source/binary commit
`b298f99f913249d299796e6a71f7a9b6b283ac1a` and passes:
- six capped login/outdoor/world-edge/dungeon/revisit checkpoints;
- one fresh uncapped-process reconnect checkpoint;
- 7/7 complete reveal/readiness checkpoints and zero invariant failures;
- 245.219-second capped and 61.321-second reconnect sessions;
- graceful logout and code-zero exit for both processes;
- zero failures;
- one expected warning covering 25 empty world-edge landblocks.
The Windows session was disconnected rather than active RDP during this run,
but the retained graphical route and screenshots completed. The gate is
correctness/lifetime evidence, not physical-display performance evidence.
## Divergence audit
This is an ownership-only port of existing retail-faithful behavior. It
introduces no approximation, alternate gameplay algorithm, polling mirror, or
asynchronous seam. No divergence-register row was added or retired.
## Rollback
```text
git revert b298f99f913249d299796e6a71f7a9b6b283ac1a
```
Revert J5 sub-slices in reverse order. Do not revert J4 or the Slice-I flat
collision cutover to mask a later J5 interaction/simulation failure.
## Next boundary
J5.2 moves use/appraisal/pickup/approach transaction identity and ordered
execution into Runtime. World rays, cursor/selection lighting, toasts,
drag/drop visuals, and retained pending-slot drawing remain App presentation.