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:
parent
b298f99f91
commit
be73bccf5a
10 changed files with 206 additions and 17 deletions
113
docs/research/2026-07-26-slice-j5-1-canonical-action-state.md
Normal file
113
docs/research/2026-07-26-slice-j5-1-canonical-action-state.md
Normal 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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue