acdream/docs/research/2026-07-27-slice-k1-single-session-headless.md
2026-07-27 07:39:56 +02:00

4.2 KiB

Slice K1 — portable single-session headless closeout

Date: 2026-07-27 Implementation: f8cb840fb15b27f61afa5c33cad6c4dba8584949 Status: COMPLETE

Outcome

AcDream.Headless is now a production, presentation-free Windows/Linux host for one real ACE session. It constructs the same canonical GameRuntime used by the graphical client and adds no bot-specific world model.

The host owns one runtime, one host lease, one LiveSessionHost, one direct typed command adapter, one policy subscription, one erasable credential, and one retryable teardown cursor. Runtime owns the character, entity/object, inventory, communication, action, physics, environment, and portal state.

Shipped mechanisms

  • Strict version-1 JSON configuration with rejected unknown fields.
  • Windows special-folder and Linux XDG config/data/cache paths with normalized command-line overrides.
  • Environment, standard-input, and credential-file providers. Linux file credentials reject symlinks and require owner-read with no group/other permissions. Passwords are not accepted on the command line or emitted in diagnostics.
  • Character selection by active index, GUID, or case-insensitive name.
  • run and validate CLI modes, stable exit codes, Ctrl+C, and Unix SIGTERM.
  • DirectGameRuntimeCommandAdapter with generation-gated routes. K1 supports session lifecycle, Say/Tell, and the four recall commands; K2 completes the remaining typed gameplay commands through this same adapter.
  • RuntimeLiveEntitySessionController, which commits inbound create/update/ delete/pickup and portal state directly into Runtime without App, UI, rendering, audio, or a parallel GUID map.
  • Exact headless portal readiness/materialization/host acknowledgements and LoginComplete. A no-window host has no graphical resource debt to await.
  • Structured JSON lifecycle/resource/failure diagnostics containing only exception types and redacted credential identities.
  • idle policy and explicit lifecycle-smoke connected-gate policy.

Reconnect finding

ACE confirms CharacterLogOff before its account/session index releases the retiring socket. Reconnecting about 350 ms later causes ACE to evict the old session and reject the replacement as Account In Use; the index disappears about two seconds later.

K1 therefore performs an explicit stop, verifies the complete teardown acknowledgement, and gives production reconnect a one-time 2.5-second quiescence suffix. Injected deterministic tests use zero delay. This is a connection-lifecycle boundary, not a steady scheduler loop. K2 moves the wait to the monotonic absolute-deadline scheduler.

Automated gates

  • Windows Runtime: 402/402.
  • Windows Headless: 25/25.
  • Windows complete Release solution: 8,728 passed / 5 intentional skips.
  • Ubuntu/WSL portable closure:
    • Core.Net 600/600
    • Content 119/119
    • Runtime 402/402
    • Headless 25/25
  • Linux-only credential permission and symlink gates pass.
  • Dependency and loaded-assembly guards continue to prove no App, UI, Silk, ImGui, OpenAL, or graphical backend is loaded.

Connected gates

Both Windows and Linux/WSL connected to the local ACE server and completed:

  1. authenticate and select the configured character;
  2. enter world and receive the CreateObject stream;
  3. issue harmless local speech;
  4. send lifestone recall;
  5. accept the exact teleport destination;
  6. complete Runtime reveal, host acknowledgements, and LoginComplete;
  7. request and confirm graceful logout;
  8. reconnect after ACE quiescence;
  9. enter the second generation;
  10. gracefully stop and converge every Runtime ownership ledger.

Both processes exited with code zero. No presentation assembly or device was loaded.

K2 carry

  • Replace K1's 15 ms single-session loop and one-time blocking reconnect suffix with one monotonic absolute-deadline scheduler.
  • Complete the remaining typed movement, selection, interaction, combat, magic, inventory, character, and social operations on the existing adapter.
  • Serialize each session's accepted inbound turn and compare graphical versus headless packet order/cadence.
  • Preserve one runtime and one mutable owner graph per session.

Rollback

git revert f8cb840fb15b27f61afa5c33cad6c4dba8584949