acdream/docs/plans/2026-07-26-modern-runtime-slice-j8.md
Erik 953c469cac docs(runtime): close Slice J and activate Slice K
Record the shared graphical/no-window reset architecture, deterministic lifecycle evidence, exact rollback point, and synchronized project guidance before beginning the Linux headless host.

Co-authored-by: Codex <noreply@openai.com>
2026-07-27 01:01:41 +02:00

301 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Modern runtime Slice J8 — no-window integration and Slice J closeout
**Status:** COMPLETE 2026-07-27 — SLICE J CLOSED
**Parent:** `2026-07-25-modern-runtime-slice-j.md`, J8
**Authorization:** the user approved Slices FL, including the J gameplay-owner
gates, on 2026-07-24
**Purpose:** prove that the exact `GameRuntime` graph now used by the graphical
client can run a complete deterministic client lifecycle without App, a
window, rendering, retained UI, audio, or backend assemblies.
## 1. Entry state
J7.1 created the root at `96ddd165`. J7.2/J7.3 cut the graphical host and
shutdown transaction over to it at
`ce41efb9e5938f79a7580476b949d172f52a1e69`. Focused, complete Release,
connected lifecycle/reconnect, and canonical nine-stop automated gates pass.
The user accepted J7's physical-display radar, paperdoll, Use/approach,
combat-facing, and both-recall matrix on 2026-07-27. J8 implementation may
begin from this accepted checkpoint.
Existing direct tests prove the individual pieces, but not the complete root:
- `RuntimeLiveSessionNoWindowTests` proves a direct session can connect, enter,
and stop.
- `RuntimeSimulationFixtureHostTests` proves movement, use, attack, cast, and
projectile behavior over separately constructed Runtime owners.
- `RuntimeWorldTransitDirectHostTests` proves login, portal, cancellation, and
host acknowledgements over a separately constructed transit owner.
- `GameRuntimeTests` proves root construction, isolation, lazy events, leases,
rollback, and terminal disposal.
J8 replaces those disconnected proofs with one end-to-end root-host proof. It
does not remove the focused tests.
## 2. Fixed boundary
The integration host lives in `AcDream.Runtime.Tests` and references only
`AcDream.Runtime` and its existing transitive Core/Core.Net/Content contracts.
It is a test host, not the Slice-K CLI.
It constructs:
- one `GameRuntime`;
- one explicit no-window host lease;
- one `LiveSessionHost` borrowing `GameRuntime.Session`;
- one deterministic `ILiveSessionOperations` fixture with a real
`WorldSession` and in-memory transport;
- one generation-scoped inbound route;
- one generation-scoped outbound command route;
- one immutable fixture-content catalog for spell and world metadata;
- one `RuntimeTraceRecorder`.
It must not construct an App adapter, duplicate entity directory, duplicate
object table, duplicate gameplay owner, second clock, second transit owner, or
second session controller.
### Canonical per-generation reset contract
The audit found one production seam that must land before the direct host can
prove reconnect honestly. `GameRuntime` owns every canonical per-session
child, but the graphical `LiveSessionResetManifest` currently invokes those
children one by one and interleaves them with App-only teardown. A no-window
host that copied that list would create a second lifecycle definition and
would not prove the Slice-K host can reuse the graphical runtime.
J8 therefore adds one Runtime-owned, retryable generation-reset transaction.
The exact public contract has these phases:
1. reset the root's canonical transit, communication, inventory, action,
character, movement, object-table, and other per-generation state in the
existing accepted order;
2. call `RuntimeEntityObjectLifetime.BeginSessionClear()` exactly once and
expose the returned exact-incarnation retirement set to one borrowed host
retirement boundary;
3. let the graphical host retire App render/physics/animation projections and
drain their queued removals, while the no-window host immediately retires
the same canonical records without constructing projections;
4. require `CompleteSessionClearIfConverged()` before clearing the canonical
player identity and permitting a new generation;
5. retain every incomplete suffix after callback failure so the same reset can
be retried without replaying a completed retirement.
The host boundary acknowledges projection retirement only. It owns no
canonical dictionary, reset cursor, generation number, or cleanup order.
App-only mouse capture, retained UI, camera, particle visibility, renderer,
audio, input, and diagnostics remain outside the Runtime transaction. The
graphical `LiveSessionResetManifest` invokes the Runtime transaction at its
existing projection-safe point; `NoWindowGameRuntimeHost` invokes that same
transaction with an immediate canonical-only acknowledgement. There is no
test-only production injection API and no alternate reset manifest.
The host applies already-decoded deterministic packets through the same Runtime
owner APIs that the graphical session route uses. Core.Net parser correctness
remains covered by Core.Net wire fixtures; J8 verifies ownership, ordering,
commands, state, generation, and teardown after decode. Test reflection may
raise a `WorldSession` event only where the public event source deliberately
has no injection API; no production test-only hook is added.
## 3. Scenario and exact ordering
One canonical scenario runs in this order:
1. Construct the root and host; capture the empty checkpoint.
2. Start generation 1 through `LiveSessionHost`.
3. Bind inbound before connect, select the first fixture character, install
exact local identity, enter world, and activate outbound commands.
4. Deliver decoded inbound fixtures:
- local-player CreateObject;
- one hostile creature;
- one usable world object;
- one container and one inventory item;
- one inventory/container mutation;
- one system chat line and one local speech line;
- one vital/character update;
- one environment/time update.
5. Advance the instance clock and execute through the root's exact owners:
- movement;
- selection plus use;
- combat mode plus attack;
- learned-spell cast;
- one projectile simulation commit.
6. Drive one accepted teleport destination through typed destination
readiness, materialization, host projection acknowledgements, world-visible
acknowledgement, and completion.
7. Capture and compare the ordered Runtime event/checkpoint trace.
8. Stop generation 1; prove the old inbound and outbound routes are inert.
9. Reconnect as generation 2 in the same process.
10. Reuse one server GUID with a new incarnation; prove no generation-1
identity, command, packet, event sequence, inventory, physics, or portal
state leaks into generation 2.
11. Stop, release the no-window lease, dispose the root, and require
`GameRuntimeOwnershipSnapshot.IsConverged`.
The fixture trace records lifecycle, entity, inventory, chat, movement,
portal, command, and checkpoint rows. Sequence numbers must be strictly
increasing within a generation and restart only when the generation changes.
## 4. Execution
### J8.1 — one direct root host
**Complete at `a9a822f2`.** `RuntimeGenerationReset` is the single retryable
canonical-generation reset transaction. Graphical App reset borrows that
transaction and retains only its presentation stages; the no-window host uses
the same Runtime root and reset owner directly.
- Add the Runtime-owned generation-reset transaction and its narrow borrowed
host-retirement acknowledgement.
- Replace the child-by-child canonical portions of App's reset bindings with
that transaction while preserving every App-only stage and the current
projection-before-identity order.
- Prove first reset, callback-fault retry, duplicate reset, and populated-root
reconnect converge without replaying completed entity retirement.
- Add a reusable test-only `NoWindowGameRuntimeHost`.
- Move the existing J5 direct-host scenario onto `host.Runtime` rather than
separately constructing six owners.
- Borrow root identity, session, entity/object, inventory, character,
communication, action, movement, environment, transit, clock, and event
source.
- Acquire and release one named host lease.
- Prove the test assembly/process loads no App, UI, Silk.NET, OpenAL, Arch,
ImGui, or renderer/audio/window type.
Gate: graphical and no-window session reset use the same Runtime transaction;
the direct root host constructs, captures a checkpoint, resets a populated
generation, and converges without a presentation assembly or duplicate owner.
### J8.2 — deterministic transport/content lifecycle
**Complete at `a9a822f2`.** `NoWindowGameRuntimeHost` drives the production
root through connect, enter, decoded state, movement, use, combat, casting,
projectile work, portal completion, stop, reconnect, stale-route rejection,
GUID reuse, and terminal convergence.
- Build deterministic session operations and in-memory transport.
- Bind the exact session lifecycle order:
reset → attach inbound → connect → select identity → enter → activate
outbound.
- Install immutable spell/world fixture metadata before its dependent packet.
- Route decoded entity, object, inventory, chat, character, environment, and
transit fixtures into the root.
- Execute movement, use, attack, cast, and projectile work through root-owned
state.
- Complete one portal using the same typed host acknowledgement contract as
App.
- Stop and reconnect, then verify generation isolation and GUID reuse.
Gate: one normalized golden trace proves all state and commands share the same
root, accepted ordering is stable, and old-generation routes are inert.
### J8.3 — cancellation, faults, isolation, and credentials
**Complete at `a9a822f2`.** Focused gates cover reset retry/no-replay,
portal cancellation before and after readiness, observer failure containment,
two simultaneous isolated roots, stale-generation routes, and
credential-safe traces.
- Cancel during connect, after inbound attach, during portal readiness, and
with a host acknowledgement pending.
- Inject route-construction, route-detach, observer, projection
acknowledgement, and terminal callback failures.
- Retry the exact retained suffix and require convergence.
- Run two roots simultaneously with different credentials, clocks, GUIDs,
inventory, chat, combat, spell, projectile, and portal state.
- Assert logs contain endpoint/user context only where intended and never
contain the password, credential record, or exception text that embeds it.
- Prove a disposed/old route cannot mutate the new generation.
Gate: every fault converges; two roots remain isolated; diagnostics are
credential-safe.
### J8.4 — complete Slice J gate
**Complete.** The exact committed binary passed:
- 395/395 Runtime tests;
- 3,731 App tests / 3 skips;
- 8,696 complete-solution tests / 5 intentional skips;
- connected lifecycle/reconnect:
`logs/connected-world-gate-20260727-004418/report.json`;
- canonical nine-stop route:
`logs/connected-r6-soak-20260727-004942.report.json`;
- the already accepted J7 physical-display matrix.
The no-window process loads no App, UI, renderer, audio, Silk.NET, OpenAL,
Arch, or ImGui assembly. The dependency and divergence audits found no new
retail deviation. Retail chat-history research also confirmed that session
end does not clear the bounded transcript: `CPlayerSystem::OnEndCharacterSession`
at `0x00562870` reinitializes the character session, while the explicit
`ClientCommunicationSystem::DoClear` at `0x0056E600` owns chat-buffer clearing.
- Run focused Runtime tests.
- Run the Release solution build.
- Run the complete Release suite.
- Run exact-binary connected graphical lifecycle/reconnect.
- Run the canonical graphical nine-stop route.
- Reconfirm the accepted J7 physical-display matrix.
- Audit dependency closure, presentation assembly loads, duplicate
constructors, mutable statics, retail divergences, and teardown ledgers.
- Update architecture, code structure, milestones, roadmap, parent and
umbrella plans, AGENTS/CLAUDE, and durable memory.
Gate: graphical and no-window hosts use the same root and owner graph; packet
and command ordering remains stable; terminal ownership converges; no
presentation/backend assembly enters the direct process. Slice J is then
closed and Slice K may add the Linux multi-session CLI and scheduler without
extracting gameplay again.
## 5. Adversarial matrix
- missing credentials and no characters;
- connect failure before and after route attachment;
- duplicate Start, stale Start, Stop, and Reconnect generations;
- inbound packet before selection and after Stop;
- command before world entry and after route retirement;
- duplicate CreateObject and GUID reuse across reconnect;
- observer throws during entity, inventory, chat, command, movement, or portal
dispatch;
- generation reset fails before host retirement, during one projection
retirement, during the drain acknowledgement, and after canonical
convergence but before identity clear;
- reset retry does not replay an already retired canonical incarnation;
- route creation succeeds but activation fails;
- detach throws once, then succeeds;
- portal cancellation before readiness, after readiness, and with each host
acknowledgement outstanding;
- projectile projection callback throws;
- host lease retained during root disposal;
- root terminal disposal retries after each stage;
- two roots use the same server GUID without sharing local IDs;
- password-shaped marker absent from trace, logs, exception messages, and
test output;
- App/UI/Silk/OpenAL/Arch/ImGui assemblies absent from the loaded-assembly set.
## 6. Non-goals
- No Linux executable or bot scheduler; those are Slice K.
- No hidden graphical process.
- No renderer, audio, UI, particle, camera, selection-marker, or portal-tunnel
stub.
- No new network parser or alternate packet order.
- No asynchronous command queue or extra frame boundary.
- No gameplay-state mirror, facade dictionary, service locator, or test-only
production injection API.
- No retail behavior change and therefore no divergence row unless the audit
discovers a pre-existing unregistered difference.
## 7. Commit and rollback discipline
J8 implementation landed as one test/integration closeout commit after the J7
visual entry gate. Its exact rollback is:
```text
git revert a9a822f206cc6021bc099988144488f3bd7c397b
```
J8 did not modify the J7 rollback point:
```text
git revert ce41efb9e5938f79a7580476b949d172f52a1e69
```