Date: October 28, 2026, America/Phoenix.
Status: in progress on codex/dusk-identity. Rename delivery: 5/5 (100%) — complete. PR https://github.com/jasona/dusk-engine/pull/2.
Product decision from the user: the engine is Dusk; Darkwind is a reference
implementation built with Dusk. The user requested this detailed plan in
llm-docs/. This documentation task does not perform the rename, change remote
repository settings or deploy an application.
#1. Outcome and fixed finish line
Deliver a coherent Dusk engine repository, developer experience and reusable player/hosting boundary. Preserve Darkwind as a working, polished reference game. Use The Meridian as the existing independent-game proof that the shared player and host do not assume Darkwind's story, controls, presentation or branding.
The implementation has exactly five milestones, R1–R5. Each completed milestone adds 20 percentage points to this rename pass. Implementation detail, discovery, extra searches or documentation alone do not advance a milestone counter.
The pass is complete when:
- Current engine-facing documentation and interfaces identify the product as Dusk; Darkwind is clearly described as a reference game.
- Reusable engine/player/host modules receive game-specific presentation and content through explicit contracts and composition boundaries.
- Darkwind retains its approved character, environment, story, identifiers and shared gameplay. Meridian launches without Darkwind-specific UI or implicit Darkwind presentation imports in the reusable player.
- Documented Dusk configuration and commands work while existing supported configuration, saved state, credentials, volumes and retained releases remain usable under the compatibility policy below.
- The bounded checks in section 11 pass or have the explicitly permitted external-state disposition, the final review captures and handoff are saved, all five milestone commits are pushed, and one final PR is prepared for main.
Then stop. New art, engine capabilities, optimizations, broad testing campaigns and optional infrastructure moves require a new scope decision.
The engine's existing 70/70 feature implementation and completed 5/5 polish pass remain separate historical counters. Do not reduce either counter because this rename starts at 0/5. This plan does not close the full roadmap's unqualified performance, device or release requirements.
#2. Scope and delivery boundaries
#Included
- Product naming, current documentation, private package metadata and engine UI.
- Game identity in the shared player, including titles, welcome/journal copy, controls, gamepad bindings, avatar/rig selection and audio integration.
- Explicit reference-game selection at service/CLI composition entry points.
- Dusk configuration names and legacy configuration compatibility.
- Clear engine-versus-game ownership and focused dependency enforcement.
- Packaging/configuration documentation that preserves existing installations.
- A prepared GitHub/Coolify naming cutover, with optional external operations performed only when covered by the user's execution authorization.
- Focused acceptance and a concise final handoff.
#Excluded
- Rewriting simulation, physics, rendering, multiplayer or persistence.
- New gameplay features or new example games.
- Another character, environment, logo-design or visual-polish campaign.
- Changing Darkwind into a different game or renaming its world to Dusk.
- A new plugin marketplace, asset system or general UI framework.
- Splitting the repository into multiple repositories, converting the project into a new package-manager/workspace system, or publishing npm packages.
- Bulk renaming historical fixtures, serialized profiles or database tables.
- Moving live storage, changing credentials or changing player domains merely to match the engine name.
- Broad benchmarks, exhaustive regression reruns or a new supported-device matrix.
- Automatically merging, changing repository settings or deploying production merely because this plan was written.
Repository work is the mandatory delivery. Renaming the GitHub repository URL, changing its default branch, renaming Coolify resources and deploying a new build are distinct external operations. Record their actual status; do not claim them completed when only their instructions/configuration are ready. Their execution is not a hidden prerequisite for calling the code/documentation rename complete. If the user explicitly adds an external operation to the required finish line, record that decision before starting it and honor that expanded requirement.
#3. Baseline and evidence to consult
The completed polish head is e997ed0. PR #1 merged it and the preceding
qualification work into main as 5f4f703. This plan was written from a checkout
on codex/engine-foundations; verify the actual current branches and remote state
when implementation starts. Do not assume the local main branch is current.
The last inspected GitHub repository was jasona/awaken-engine, with the default
branch still reported as codex/engine-foundations. That is an observation to
recheck, not an instruction to change the default branch during planning.
Relevant existing documents:
- Engine architecture and product plan.
- Implementation roadmap.
- Current engine delivery state.
- Frozen feature inventory.
- Game SDK and independent games.
- Retained engine builds.
- Coolify deployment.
- Release qualification and pending Docker check.
- Approved character and completed polish acceptance.
- Root agent instructions.
The earlier Docker handoff remains associated with 0546627; the user said they
would run it, but no passing external result was reported in the recorded handoff.
GitHub Actions also failed to start PR #1's jobs because GitHub reported an account
billing/spending-limit problem; 23 jobs had no executed steps. Recheck live status
before relying on CI. Neither historical limitation is a passing rename result.
#Observed implementation seams
| Area | Current state | Intended treatment |
|---|---|---|
package.json and root lockfile |
Private root package is darkwind-engine. |
Rename root metadata to dusk-engine; keep private status, dependency versions and lockfile integrity. |
README.md |
Opens with Darkwind and mixes engine, game and hosting instructions; some introductory art wording is stale. | Introduce Dusk first; link to a dedicated Darkwind reference-game guide and current acceptance. |
packages/ |
Engine packages are already isolated from game imports by the package boundary checker. | Preserve this architecture; do not reorganize neutral package directories for branding. |
packages/sdk/index.ts |
Neutral source import path; serialized API value is darkwind-game-sdk.1. |
Brand the source API/documentation as Dusk SDK while preserving the supported serialized value. |
| Plugin, extension, agent-tool, wire and checkpoint modules | Several versioned identities contain darkwind. |
Preserve them as documented compatibility identifiers in this pass. |
apps/editor/main.ts, editor.html |
Darkwind wordmark and engine-tool page title. | Dusk World Atelier; retain editor access and saved history. |
apps/probe/main.ts, diagnostics.html, physics.html |
Engine diagnostics/lab pages carry Darkwind branding. | Dusk Observatory and Dusk Physics Lab; fixture labels identify the game being demonstrated. |
apps/player/main.ts |
Direct Darkwind control/gamepad imports, Darkwind-named world variable, keeper-story detection and game copy. | Generic world/session ownership plus an injected game presentation adapter. |
apps/player/graphics.ts, graphics.worker.ts, graphics-revision.ts, catalog.ts |
Direct imports of Darkwind traveler/rig assets. | Receive an admitted presentation profile/catalog; preserve avatar behavior across worker and recovery paths. |
apps/player/audio.ts |
Generic browser audio lifecycle imports Darkwind sound graph/frame functions. | Inject the graph/frame adapter; keep sound generation and story selection under game ownership. |
services/relay/server.ts |
Reusable relay has a Darkwind default import. | Require an explicit world at the reusable boundary; select demos at entry points. |
services/relay/main.ts, services/persistent/world.ts, services/routing/main.ts |
Composition code selects reference worlds. | Make that role explicit and consistently support independent game releases. |
tools/cli/editor.mjs, dev.mjs, author.ts, meridian.mjs |
Tooling/default selection and environment variables use existing conventions. | Dusk-facing output/configuration with explicit game commands and compatible aliases. |
Dockerfile*, deploy/entrypoint.sh, deploy/healthcheck.mjs |
Images bake legacy environment defaults; the shell takes the storage lock before Node starts, and health checks run independently. | Resolve aliases/defaults consistently before directory locking, service startup and health probing. |
compose.coolify.yaml, compose.beta.yaml |
Reference-game services and named save volumes use Darkwind names. | Keep game names and existing volume identity; label generic engine services appropriately. |
games/darkwind/ |
Owns the reference world, approved character integration, story, sound and authored arrival. | Keep the game directory and game identity. |
games/cooperative-puzzle/game.ts |
Meridian already uses the public SDK. | Reuse it as the independent-game acceptance case. |
This is a starting inventory. Inventory remaining direct game imports and public configuration readers once during R1/R3, record exceptions, then implement. Do not turn repeated repository searching into a separate delivery milestone.
#4. Naming and ownership policy
#Public product vocabulary
| Concept | Name after this pass |
|---|---|
| Engine/platform | Dusk |
| Private root package | dusk-engine |
| Public source API/documentation | Dusk SDK |
| Editor | Dusk World Atelier |
| Diagnostics | Dusk Observatory |
| Physics workbench | Dusk Physics Lab |
| Generic runtime/server output | Dusk runtime, relay, room host, or control service, as appropriate |
| Reference game | Darkwind |
| Reference game's subtitle/content | Existing Darkwind/The First Light story names |
| Other existing games | Their own names, including The Meridian |
| Optional engine credit in game UI | Powered by Dusk; subordinate to the game's identity |
| Proposed repository slug | dusk-engine, subject to availability and authorized external cutover |
Keep neutral names such as packages/render, packages/sdk, WorldDefinition,
SDK_API, /api, /room and /engines/<hash>/. They already describe their
responsibilities and do not need a Dusk prefix.
Keep Darkwind names in Darkwind game content, assets, credits and explicit demo
fixtures. A game server named darkwind is valid when it is serving Darkwind.
A legacy volume named darkwind-arrival-v10 is also valid operational identity.
The completion criterion is correct ownership, not zero search matches.
#Classify each old-name occurrence
Before replacing a name, classify it as one of:
- Current engine-facing branding: change to Dusk.
- Darkwind game identity/content: keep Darkwind.
- Compatibility or persistent identity: retain, or use the explicitly defined compatible alias policy; never replace blindly.
- Historical evidence, fixture or credit: preserve its factual meaning.
- Incidental internal label: rename when safe and relevant to a touched file; do not start a repository-wide cosmetic refactor for these alone.
Examples: a worker debug name such as darkwind-render can become dusk-render;
Darkwind's world ID cannot become dusk; an engine schema's human-readable title
may change only after checking whether it participates in a frozen identity.
#5. Target engine/game composition
Keep one repository. Do not move the whole player into the Darkwind directory: it is a reusable host and must continue to run SDK games and editor playtests.
Dusk packages: schema / authoring / compiler / simulation / render / net / SDK
^
|
Reusable player + editor + service factories
^
|
Explicit host/bootstrap and trusted presentation registry
/ \
Darkwind world + adapter Meridian world + adapterDependency rules:
- Engine packages never import
games/,apps/or service bootstraps. - Reusable player modules do not import
games/darkwind/*directly. - Service factories consume a world/release/configuration explicitly; operator entry points may intentionally select named installed examples.
- Game adapters depend on supported engine contracts. Extend the public SDK only where an actual source-level extension is necessary for these adapters.
- Diagnostics may deliberately load named game fixtures through a fixture registry. Such imports are explicit examples, not hidden runtime defaults.
- Boundary enforcement covers dynamic and type imports, following the existing checker. New checks must protect a real ownership boundary rather than simply banning the word Darkwind.
#Minimal presentation contract
Create a small explicit presentation contract using existing types. This is a source/bootstrap boundary, not a new extensible UI/plugin framework. Its fields must cover the currently hardcoded choices:
| Concern | Game/adapter supplies | Dusk supplies |
|---|---|---|
| Identity | Display name, introductory copy, optional subtitle/credit choices. | Page/HUD rendering, safe text handling, generic fallback. |
| Controls | Action map and gamepad bindings or explicit shared defaults. | Input handling, rebinding, controller/touch lifecycle. |
| Traveler | Admitted model/catalog reference, rig options, color choices and attachments. | Asset admission, rig evaluation, rendering, multiplayer projection and recovery. |
| Audio | Graph and frame adapter, or explicit silent/default profile. | Browser activation, mixer ownership, pause, levels and disposal. |
| Game UI | Darkwind-specific objective/journal/satchel descriptions and story selection. | Generic menus, settings, resource/action UI and accessible interaction shell. |
| Persistence | A stable mapping to the admitted game identity and existing namespaces. | Save/session lifecycle and isolation; the display name never selects credentials. |
Main-thread trusted adapters may supply normal typed functions where existing
integration requires them. Functions must not be sent through postMessage,
serialized into a world file, downloaded as executable code from an arbitrary
URL, or selected by an unchecked query parameter. Worker initialization receives
only validated, structured-clone-compatible profile/catalog/rig data.
Use an explicit trusted registry/bootstrap for installed presentation adapters.
For portable data-only game releases, use a generic Dusk presentation or an
operator-installed adapter bound to the admitted game/release. Preserve the
existing restrictions on executable creator code. Do not introduce eval, remote
module imports or arbitrary filesystem imports as part of branding.
Avoid a new world-format migration for presentation branding. Prefer source or host metadata and the existing asset catalog. If implementation discovers that persisted format changes are genuinely required, document the concrete missing capability and the smallest proposal before expanding this frozen pass.
#Shared defaults and the approved character
Darkwind must retain the approved Vita appearance, existing rig behavior, lantern attachment and visual direction. Moving an asset's ownership does not authorize regenerating or redesigning it.
If the current traveler is intentionally a shared starter asset, move its common model/base rig into a clearly shared starter-asset module with preserved binary bytes, source attribution and license. Let Darkwind add its own attachments and sound/story behavior. Do not create a shared module that still imports Darkwind behind another filename. Other games may explicitly choose the same shared asset. Do not duplicate large binaries solely to remove an import.
A generic game must have usable defaults. Missing presentation metadata must not silently activate Elowen's story, a Darkwind journal or Darkwind sound cues.
#Critical integration paths
Audit and update the profile flow through all currently supported paths:
- Normal player startup and streamed content admission.
- Main-thread graphics and OffscreenCanvas/graphics worker initialization.
- Device-loss/worker recovery and simulation restart.
- Portal previews and ordinary place transitions.
- Live authoring revisions, model catalog staging and published playtests.
- Persistent/regional room entry and retained engine startup.
- Avatar equipment, seated/ragdoll/swimming presentation where it already exists.
Preserve existing behavior and version fences. Exercise the affected paths using existing focused checks; do not create a new comprehensive test matrix here.
#6. Compatibility invariants
#Preserve persistent and serialized identity
| Surface | Rule for this pass |
|---|---|
| Darkwind world/release/entity/interaction IDs | Preserve them; branding does not create a new world or change story identity. |
| Darkwind browser saves and return credentials | Keep their current game namespaces and migration readers. |
| Editor identity/history/authentication keys | Preserve reads and identity. Rebrand UI independently; do not log out builders or fork their history identity. |
| Generic browser preferences | Preserve current keys for this pass, or use an explicit read-old/write-new migration with old values retained; no blanket storage clear. |
PostgreSQL dw_* tables and identity schemas |
Keep schema names and existing migrations. No database rename migration is needed for product branding. |
SDK_API, plugin/extension/agent-tool serialized values |
Keep supported versioned values such as darkwind-game-sdk.1, darkwind-plugin.1, darkwind-extension.1 and darkwind-agent-tools.1. |
| Binary WebSocket subprotocol and wire dictionary | Preserve negotiated compatibility, including darkwind.binary.1.*; no cosmetic wire revision. |
| Simulation/owned-physics checkpoint profiles | Preserve current and legacy readers and their literal identities. |
| Golden fixtures, archived recordings and historic receipts | Do not bulk regenerate or edit brand strings in frozen evidence. |
Retained engine registry and /engines/<hash>/ |
Preserve old bundles and pins byte-for-byte; keep old entry points and runtime ABI expectations usable. |
| Imported assets and licenses | Preserve source attribution and content identities when moving files. |
| Local data directories and Docker volumes | Retain the actual existing mount and contents, even when a display label changes. |
| Origin policy, passwords and session signing keys | Preserve their semantics and values; the new name does not imply a new domain or reset. |
New builds naturally receive new build hashes. That is expected. Do not rewrite old bundles, relabel existing hashes, modify old save headers or fabricate a matching checksum after a rename. A later true protocol/schema migration belongs in its own versioned work item.
Create a small compatibility inventory during implementation: file/location, legacy identifier, why it remains, and the relevant existing check. Keep it concise and checkable. It is not a second roadmap or a reason to rename every legacy string.
#Environment-variable contract
Use DUSK_* as the canonical documented prefix for supported engine operator
settings. Continue accepting the corresponding DW_* settings. Do not make core
engine packages read process environment; normalize at application/tool/service
boundaries and pass validated values inward.
A single shared resolution policy must be used by Node entry points and build launchers:
- If only the canonical key is present, use it.
- If only the legacy key is present, use it.
- If both are present with the same raw value, accept them.
- If both are present with different raw values, fail with the two key names and a clear correction. Never print their values; either may contain secrets.
- Presence is not truthiness. Preserve valid explicit empty values,
0values and existing default behavior; apply existing semantic validation afterward. - Preserve ordinary non-project settings such as
PORT,PGHOST,NODE_ENVand Playwright/GPU options and their existing documented precedence. - Do not silently change defaults for directory, room, backend, ports or origin policy while introducing the aliases.
Initial public mappings include:
| Canonical setting | Legacy alias | Meaning |
|---|---|---|
DUSK_ALLOWED_ORIGINS |
DW_ALLOWED_ORIGINS |
Exact allowed browser origins. |
DUSK_ROOM_PASSWORD |
DW_ROOM_PASSWORD |
Private room passphrase. |
DUSK_RELAY_PORT |
DW_RELAY_PORT |
Room HTTP/WebSocket port. |
DUSK_HTTP_PORT |
DW_HTTP_PORT |
Development frontend port. |
DUSK_DATA_DIR |
DW_DATA_DIR |
Existing persistent directory. |
DUSK_STATIC_DIR |
DW_STATIC_DIR |
Packaged client directory. |
DUSK_ENGINE_BUNDLE |
DW_ENGINE_BUNDLE |
Selected retained runtime. |
DUSK_GAME_FILE |
DW_GAME_FILE |
Explicit portable game release. |
DUSK_GAME_SOURCE |
DW_GAME_SOURCE |
Operator-selected source game at image build time; retain the trusted source-build boundary. |
DUSK_PLAYTEST |
DW_PLAYTEST |
Named installed reference fixture. |
DUSK_PHYSICS_BACKEND |
DW_PHYSICS_BACKEND |
Existing backend selection. |
DUSK_EDITOR_TOKEN |
DW_EDITOR_TOKEN |
Private editor access. |
DUSK_PLAYER_ACCOUNTS |
DW_PLAYER_ACCOUNTS |
Account mode. |
DUSK_AUTHORING_WORKSPACE |
DW_AUTHORING_WORKSPACE |
Existing stable workspace. |
DUSK_DATABASE_URL |
DW_DATABASE_URL |
Database connection string. |
DUSK_PERSISTENT_ROOM |
DW_PERSISTENT_ROOM |
Existing room identity. |
DUSK_HOST_PORT |
DW_HOST_PORT |
Local Compose host-port mapping. |
This is the initial list, not permission to ignore other supported service settings. Enumerate documented control/routing/room-host/build-worker options and place each in the same mapping inventory. Keep internal fixture switches separate from the public operator API. Do not introduce a naming change by silently removing one of the existing supported switches.
Resolve configuration before a dependent module reads it at import time. Either inject resolved values into consumers or normalize in a bootstrap before loading the dependent entry point; a call after static imports may be too late.
Container defaults need explicit treatment. The current Dockerfiles bake several
DW_* defaults into the image. An operator supplying only DUSK_RELAY_PORT must
not receive a false conflict with an inherited image default for DW_RELAY_PORT.
For new images, move defaults into the per-role resolver or explicitly distinguish
default provenance from operator input. Do not solve this by always preferring
one prefix: two genuinely supplied conflicting settings still fail. Preserve the
different established default ports/settings for relay, persistent, routing and
control images. Document the build-argument policy separately from runtime env.
Normalize the data-directory selection before deploy/entrypoint.sh creates the
directory or opens .relay.lock. The shell and Node must lock and write the same
directory. Preserve the existing exec/file-descriptor inheritance behavior; do
not accidentally release the writer lock while inserting a bootstrap. Use a safe
launcher/configuration handoff, not generated shell eval containing secrets.
Docker health checks are separate processes and do not automatically inherit
environment variables changed by PID 1 after startup. Update
deploy/healthcheck.mjs to resolve the same container settings/defaults itself,
including a canonical-only custom port. A server starting on one port while the
health check probes another is a rename regression, not successful alias support.
For retained older engines and existing .mjs launchers, construct a compatible
child environment with the resolved legacy names they already understand. The
normalized canonical and legacy values must agree. Do not rewrite or require
rebuilding a retained runtime just to consume a new prefix.
Vite/build selection requires its own explicit public whitelist. If adding
VITE_DUSK_PLAYTEST, retain the existing VITE_DW_PLAYTEST selection and define
matching resolution. Never copy arbitrary DUSK_*/DW_* values into a browser
bundle. Database URLs, editor credentials, passphrases and signing material remain
server-only. Browser-visible fixture selection must agree with server selection.
Compose interpolation must follow the same documented conflict policy. Do not
use a nested fallback expression that silently chooses one conflicting value or
mistakes an intentionally empty value for an unset value. If normalization must
occur in a wrapper/preflight rather than YAML, document the supported invocation
and keep the existing Coolify invocation working. Verify effective container
values, not just the names in .env.example.
#7. Milestones and acceptance
#R1 — Product identity, inventory and documentation — 20%
Work:
- Add the Dusk terminology and compatibility classification from this plan to the current implementation handoff so future agents do not restart the old polish backlog or reinterpret Darkwind as the engine.
- Rename the private root package and matching root lockfile metadata. Preserve versions, dependency resolution, scripts and private status.
- Rewrite the root README around Dusk: what it is, how to open the tools, how to run Darkwind, how to run another game, and where hosting/qualification live.
- Create
games/darkwind/README.mdfor the reference-game overview, controls, story, approved art, current playtest commands and known operational bounds. - Update current titles and explanatory text in engine/SDK/architecture docs. Preserve dates, old evidence, historical filenames and factual old branding.
- Perform one targeted inventory of direct Darkwind imports, public operator variables, engine UI labels and persistent identifiers. Record ownership and the small set of required exceptions.
Acceptance:
- The README identifies Dusk as the engine and Darkwind as a reference game.
- Root package/lockfile metadata agree and dependency versions are unchanged.
- Engine and game instructions are clearly separated and linked.
- The inventory names concrete file targets for R2–R4 and compatibility exceptions.
- A root/SDK documentation review finds no current wording presenting Darkwind or Awaken as the engine product, outside documented historical/compatibility cases.
Delivery: one usable documentation/metadata commit; report 1/5, 20%. Do not claim implementation of the player boundary or new runtime compatibility yet.
#R2 — Dusk tooling and engine-facing UI — 40%
Work:
- Update the editor wordmark/page title, Observatory wordmark/page title and Physics Lab title to their Dusk names.
- Rebrand generic engine diagnostic reports, authoring export download labels, startup output and user-facing errors where the name identifies the engine.
- Keep game exports and recordings correctly associated with their actual game; changing an outer download filename does not change its serialized contents.
- Keep the existing polished layout and visual language. Use the existing vector/text approach; no new bitmap logo, typography replacement or design exploration is required.
- Keep Darkwind's game title and wordmark. Add the restrained engine credit only in an appropriate existing build/about/diagnostics surface.
- Preserve editor authentication/history keys, URLs and commands while labels change. Do not rename ID selectors solely for branding.
Acceptance:
- The editor visibly says Dusk World Atelier.
- Diagnostics visibly say Dusk Observatory; the physics tool says Dusk Physics Lab.
- A loaded Darkwind playtest remains Darkwind and retains the approved appearance.
- Existing editor access and a previously saved editor identity still work.
- Save actual editor/diagnostics screenshots and one Darkwind game capture.
Delivery: one visible tooling commit and screenshots; report 2/5, 40%.
#R3 — Explicit game presentation and host boundary — 60%
Work:
- Implement the minimal contract in section 5 using the existing player, renderer, input, audio and SDK types. Keep it narrow enough for Darkwind and Meridian.
- Move Darkwind-specific welcome/story/objective/journal behavior into the
reference adapter. Rename the generic player's
darkwindworld variable to a neutral role name where it is genuinely a loaded arbitrary world. - Pass action maps, gamepad settings, traveler/rig data and sound adapters into reusable owners. Remove direct Darkwind imports from graphics creation, graphics-worker startup, revision/recovery catalog code and generic audio.
- Preserve explicit shared starter assets and Darkwind-specific attachments as described above. Validate asset/rig admission using existing boundaries.
- Remove the implicit reference-world default from reusable relay/server factories. Adapt their explicit callers and test fixtures in the same commit.
- Keep demo selection in a clearly named composition registry/bootstrap.
- Ensure published, streamed, persistent and regional game selection use the admitted world/release; a cosmetic display name is never a game identity.
- Add focused boundary enforcement with explicit fixture/bootstrap exceptions. Do not extend a no-game-import rule to legitimate test/demo composition code.
- Preserve source SDK import paths and the serialized API values from section 6. Do not turn the reference implementation into a forced full SDK rewrite.
Acceptance:
- Reusable player modules and service factories have no direct Darkwind imports or hidden keeper-story fallback, except listed composition/fixture boundaries.
- Darkwind loads through its adapter with the same story, controls, sound and approved traveler; the existing shared journey remains usable.
- Meridian loads through the same player with its own identity and game UI; no Elowen/lantern-house objective or Darkwind welcome text appears.
- Main/worker initialization and the affected recovery/revision paths carry the same admitted profile and catalog. Required existing focused checks pass.
- Opening an older portable game release does not fail solely because it names the legacy SDK API.
Delivery: one substantive integration commit; report 3/5, 60%. Internal refactor subtasks do not earn separate progress increments.
#R4 — Commands, compatible configuration and deployment readiness — 80%
Work:
- Add
npm run dev:darkwindas the clear reference-game entry. Recommended behavior: launch the current polished arrival profile through the existing art launcher. Keepdev:art,dev:editor,dev:meridian,devand documented profile commands compatible; do not change the behavior ofdevcasually. - Rebrand CLI output and help as Dusk while retaining explicit game names such as
author ... import darkwindand installed Darkwind fixture names. - Implement the canonical/legacy environment policy, inventory all public entry points and propagate it into child processes/build selection.
- Update
.env.example, run guides, Docker/Compose configuration and Coolify instructions with clear public setting names and legacy examples. - Preserve service keys that name the reference game, actual data directories, image user/permissions, health checks, internal ports, proxy endpoints and shutdown semantics unless an independently necessary change is demonstrated.
- Record a deployment mapping that distinguishes displayed product name, service key, physical volume, data path, source repository and player domain.
- Prepare the optional external naming cutover in section 9. Execute it only if the user's current execution authorization covers those resource changes.
Acceptance:
- Documented Dusk commands start the intended tools/reference game.
- Legacy command aliases continue to resolve to their documented behavior.
- Canonical-only, legacy-only, matching dual-key and conflicting dual-key settings follow the defined policy; conflicts never disclose secret values.
- New configuration reaches retained children under the legacy names they need.
- Existing
DW_*Coolify configuration remains supported; no existing volume or session-signing file is recreated because of naming. - Compose configuration resolves with the intended environment and mount paths.
- The handoff states whether external repository/default-branch/Coolify display changes were applied, intentionally retained, or prepared pending authorization. These labels do not masquerade as a performed deployment.
Delivery: one compatible tooling/configuration commit; report 4/5, 80%.
#R5 — Focused integration, documentation closure and PR — 100%
Work:
- Complete the fixed acceptance set in section 11 on the integrated candidate.
- Fix demonstrated rename regressions. Record unrelated or nonblocking findings in the existing follow-up notes; do not expand this five-milestone scope.
- Finish terminology/links, the compatibility inventory, exact run instructions, concise acceptance record and final screenshots.
- Update this plan's status and the current delivery block to completed. Keep the old feature/polish counters and independent qualification limits explicit.
- Push the final milestone and prepare one PR into main summarizing the complete rename, compatibility policy, validation and external cutover status.
- Merge only when covered by the user's instruction; do not infer merge or production deployment authorization from writing or reviewing this plan.
Acceptance:
- Every mandatory item in section 11 is passed and linked to a concrete command or rendered review; allowed external limitations are named accurately.
- Current engine surfaces use Dusk, game surfaces use their game identities, and retained legacy identifiers are explicitly classified.
- Darkwind and Meridian demonstrate the reusable player/host boundary.
- Old data/configuration continuity is demonstrated by the bounded checks.
- Screenshots, commit IDs, run instructions, remaining limitations and the PR are handed over in one concise record. No unfinished mandatory rename work remains.
Delivery: final commit, pushed branch and PR; report 5/5, 100%. Stop. Optional external cutover and the earlier Docker/performance qualification retain their own explicit status; neither becomes an automatic next task.
#8. Execution sequence and repository discipline
- Read this plan, root instructions and the current progress block. Confirm the user's implementation authorization and the exact requested external scope.
- Inspect the clean/dirty checkout, current branch, remotes and latest main. Preserve user changes. Commit/carry this requested plan deliberately if needed; never discard it to make the worktree clean.
- Create
codex/dusk-identityfrom the current intended main baseline, or use an equivalent user-requested branch. The product rename does not require renaming the local checkout directory/home/jason/coding/dw-web. - Keep one milestone active at a time, in order. Finish usable increments after focused checks and commit/push each milestone promptly.
- Report the milestone counter, what changed, what the user can try and any relevant deferred limitation. Show a screenshot for visible milestones.
- Keep one acceptance section per milestone. Do not commit duplicate raw report dumps, huge log collections or a dossier for every wording change.
- Run the final fixed checks once after integration. Repeat a passing check only for a changed path, actual failure or concrete unresolved risk.
- Open one final PR to main. Keep changes limited to this rename and demonstrated regressions caused/exposed by it. Preserve history and the source branch.
- Stop after R5; do not resume prior art, benchmark, diagnostics or engine backlog.
If the original five items prove insufficient for a mandatory requirement, identify the exact requirement and blocking dependency. Present the smallest scope amendment instead of silently adding a sixth milestone or changing the percentage denominator. Preparation, blocked external operations and partial milestones must be reported honestly.
#9. GitHub and Coolify cutover
#Repository naming
Recommended eventual repository name: jasona/dusk-engine. Availability and
permissions are not established by this plan. Retain the existing repository and
history; do not create a replacement repository and copy the source into it.
Before an authorized rename:
- Record current repository URL, default branch, branch protection/rulesets, workflows, hooks, integrations and any consumers of the old URL.
- Decide whether main should become the default branch. Last inspection reported the development branch as default; renaming the repository alone does not fix that. Do not silently bundle this change into the name operation.
- Prepare local
origin, current docs, CI references and Coolify source changes for the exact new repository identity. - Keep the unrelated
darkwind-sourceremote and its upstream repository intact. The engine rename does not authorize moving or deleting it.
After an authorized rename:
- Verify the new remote and branches, update the local origin and current links, and confirm the PR/history remain accessible.
- Update connected applications to the new URL explicitly. Verify actual access; do not rely on an assumed redirect for deployment integrations.
- Keep older published evidence and historical links understandable; avoid rewriting old commits or all old reports.
If the repository URL is intentionally retained, Dusk branding still ships. State
Repository URL: retained as jasona/awaken-engine in the handoff rather than
pretending the remote was renamed.
#Deployment/storage mapping
Capture the actual values from the chosen application before any external mutation. Examples from the source are logical names, not proof of the physical Coolify resource/volume names on the server.
| Item | Rename policy |
|---|---|
| Engine product/tool display name | Dusk. |
| Darkwind game/application display name | Keep Darkwind, optionally identify Dusk as the engine. |
compose.coolify.yaml game service darkwind |
Valid game identity; retain existing proxy/service mapping. |
compose.beta.yaml service darkwind-beta |
Valid reference-beta identity; no automatic service-key change. |
Logical volume darkwind-room |
Preserve the existing physical mount and data. |
Logical volume darkwind-arrival-v10 |
Preserve the current reference-beta save volume. Do not create a new volume merely because the engine changed names. |
Container data path /data |
Preserve it and existing ownership/permissions. |
| Container user/group and port 8787 | Preserve current values unless separately changed for a demonstrated reason. |
Local directories such as .data/hearth, .data/arrival-art.10, .data/meridian.1 |
Preserve existing room separation and data continuity. |
| Database URLs, room IDs and authoring workspace | Keep their actual identities. |
| Password/session signing material | Preserve and keep out of logs, source and client bundles. |
| Public hostname and allowed origins | Preserve current origins; resource display names do not change browser origins. |
| Retained engine bundle storage | Preserve all required old pins and artifacts. |
A renamed Compose project, resource, service or volume key can select a different
physical volume. If an external operational rename is genuinely needed, map the
old physical volume explicitly using the supported deployment configuration.
Record and review the resolved mount before deploying. Do not run down -v, prune
volumes, reset credentials or make a new empty room look like a successful rename.
#Authorized cutover and rollback
- Finish and review the code/configuration first.
- Record the running commit/image, actual mounts, room identity and configuration key names. Keep secret values in the existing secure operator system.
- Follow the existing backup procedure for that storage profile. For the local JSON profile, stop the writer before copying the full volume, including the signing key. Database profiles use their established consistent backup path.
- Resolve and inspect Compose/container settings and the intended exact volume.
- Apply only the authorized repository/resource/configuration changes. A source push is not a request to create a replacement Coolify application or storage.
- If deployment is authorized, deploy one instance using existing shutdown and health semantics. Verify health, two-player admission and an existing saved change across replacement on that exact candidate.
- On failure, restore the previous source/image and configuration with the same storage identity. Do not edit save headers or reinterpret old hashes.
Do not run old code against state that was actually migrated incompatibly. This plan avoids such migrations; any real schema migration needs its own rollback strategy. Record the exact tested commit and state compatibility.
Actual hosted restart/volume acceptance requires Docker/server access and explicit deployment scope. If unavailable, record the prepared mapping and exact remaining operator action. Do not repeat unrelated checks to fill the wait or claim that static Compose validation proves a restart.
#10. Documentation and artifact changes
Mandatory current documentation targets:
- Root README: Dusk introduction, engine tools, examples and hosting links.
games/darkwind/README.md: reference-game purpose, controls, art/credits, persistence/run instructions and current known bounds.docs/ENGINE_PLAN.md: Dusk ownership/product terminology; existing requirements remain intact, including unqualified performance/device criteria.docs/GAME_SDK.md: Dusk SDK naming, supported serialized legacy API values and explicit game/presentation integration instructions.docs/ENGINE_PROGRESS.mdand rootAGENTS.md: the currently authorized rename milestone and final stopping point; preserve historical acceptance facts.docs/COOLIFY.md,.env.exampleand relevant service guides: canonical/legacy configuration, exact storage mapping and old-installation compatibility.docs/ENGINE_PINNING.md: Dusk product name with retained ABI/artifact identity.docs/RELEASE_CANDIDATE.md: a separate rename acceptance section and the exact state of prior Docker/CI qualification; do not overwrite old results.- This plan and
llm-docs/README.md: milestone status and final PR link when done.
Keep historical dated entries as history. Correct current false claims such as old proxy-art wording without rewriting the record of what was once shipped. Use a small explicit list of surviving compatibility names instead of a blanket statement that every Darkwind string is now obsolete.
Retain actual screenshots for the Dusk editor, Dusk Observatory, Darkwind and Meridian, plus the relevant final shared review. Use current render captures; do not substitute concept art or fake renamed screenshots. One coherent set is sufficient. No new logo/image-generation task is required.
#11. Fixed validation and acceptance matrix
These are the rename's fixed checks. Prefer existing fixtures and journeys; add focused checks only for the new boundary/alias behavior or a demonstrated regression. Documentation-only R1 work does not require a full test run.
| ID | Required check | Acceptance |
|---|---|---|
| V1 | Package/lockfile and source checks | Install metadata is consistent; npm run check passes type, dependency-boundary and generated-wire checks. |
| V2 | Production packaging | Existing production build command succeeds; player, workers, editor, server and retained-engine artifacts resolve required presentation modules. |
| V3 | Canonical/legacy environment resolution | Canonical-only, legacy-only, equal dual values, unequal dual values, explicit empty/zero, image-default provenance and relevant mixed child/runtime cases follow section 6. Startup locking and independent health probes resolve the same intended directory/port. Secrets are absent from diagnostics/client artifacts. |
| V4 | Dependency ownership | Engine packages retain their current restrictions; generic player/service factories do not import Darkwind; explicit bootstrap/demo/fixture exceptions are named and bounded. |
| V5 | Engine UI | Open Dusk editor/Observatory/physics pages; confirm labels, current tool links and a useful viewport. Retain actual captures of the main renamed tools. |
| V6 | Darkwind continuity | Reuse the existing focused two-traveler house/garden/cart/house journey, including ordinary grounded disembarkation and return. Preserve approved art, controls, sound integration and readable UI. |
| V7 | Independent game | Run Meridian through the shared player, load/edit its world through the editor, and perform one existing game interaction or publish/playtest smoke. Confirm its identity and lack of Darkwind story UI. |
| V8 | Existing data/format continuity | Exercise representative existing save/editor identity, legacy game-release/API and retained runtime/profile readers affected by the changes. Keep unchanged golden values; no branding-only save reset. |
| V9 | Packaging/deployment configuration | Resolve documented Compose settings and inspect the effective environment/mount mapping for new and legacy settings. Preserve actual old volume identity. This is not hosted restart evidence. |
| V10 | Handoff | Final commit IDs, commands, screenshots, compatibility exceptions, external-operation status, limitations and PR are documented in one concise acceptance record. |
Commands available in the current repository include:
npm ci
npm run check
npm run build
npm run dev:editor
npm run dev:meridian
npm run dev:artR4 adds the explicit npm run dev:darkwind alias. Use Node 22.23.4 as pinned by
the current repository unless the user separately changes the supported runtime.
Do not upgrade dependencies or the runtime as part of this naming pass.
For the existing isolated rendered Darkwind journey, use the maintained arrival
browser test and its normal fixture environment. At the planning baseline the
continuous case is in tests/browser/arrival-art.spec.ts and named
polish finish line shares house garden cart and house in one journey. Update its
selection/configuration consistently if the canonical prefix is introduced; keep
legacy invocation coverage. Use the known physical Chromium profile when
available, and report the actual renderer/device route rather than calling a
software-rendered check a physical GPU check.
Preserve the established focused checks for worker/main startup, device recovery, revision/catalog replacement, SDK game loading, configuration and retained-engine launching where the implementation changes those paths. Record the selected commands in the milestone acceptance before running them. Do not quietly grow this list into all renderer, physics, persistence and browser suites.
A passed check is rerun only after a relevant change/failure or a specific unresolved risk. A failure introduced by the rename is fixed in the active milestone. A pre-existing unrelated failure is recorded with its reproduction and impact; it does not authorize broad cleanup. An unresolved failure on a mandatory rename path is not a pass.
#External checks and honest reporting
- Existing Docker availability is an external prerequisite. Source/build and static Compose checks can pass without claiming Docker acceptance.
- If a new container smoke is actually run, identify the exact candidate and
actual selected game/presentation profile. A result for
0546627is not a result for a later Dusk candidate. - If GitHub Actions cannot start because of billing, report that condition and the actual local checks. Do not call CI green, disable checks to hide the failure, bypass a required protection, or wait indefinitely while adding work.
- Any required merge/deployment protection remains enforceable. Resolve concrete permissions/access when needed; routine local implementation does not need repeated user approval.
The final handoff separates code acceptance, CI status, repository/resource cutover and Docker/hosted acceptance. One category does not imply another.
#12. Risks and prescribed responses
| Risk | Response within this plan |
|---|---|
| Blind replacement changes a protocol/profile and invalidates old state. | Classify old names; preserve serialized identities and old readers; add the small exception inventory. |
| Branding depends on detecting the keeper or a hardcoded world ID in generic UI. | Use the explicit trusted presentation adapter and a neutral fallback. |
| A renderer worker loses the game profile during revision/recovery. | Carry validated cloneable descriptor data through the existing initialization/recovery boundary and exercise the affected focused check. |
| Adapter selection becomes arbitrary executable creator code. | Use installed trusted registries and existing asset/data admission; no remote/evaluated module loading. |
| An avatar move loses licensing or changes approved art. | Preserve bytes, attribution and rig behavior; separate game attachments from shared defaults. |
| A new environment prefix works in one CLI but not children, Vite or older engines. | Normalize consistently at all operator boundaries; test canonical/legacy and retained-child mappings. |
| A renamed resource selects an empty volume or breaks a proxy route. | Preserve real names/mounts; prepare and inspect the actual deployment mapping before authorized cutover. |
| A browser namespace rename discards saves, settings or editor identity. | Preserve keys or implement a targeted non-destructive migration; never clear storage as acceptance. |
| Old evidence is rewritten to look like Dusk was already tested. | Preserve historical results and record the exact new candidate/checks separately. |
| The pass turns into a new architecture/art/performance project. | Freeze R1–R5; fix demonstrated blockers, record follow-ups, stop at the defined finish line. |
#13. Progress ledger and delivery template
Initial status at plan creation:
| Milestone | State | Delivered commit | Counter after acceptance |
|---|---|---|---|
| R1 — Identity/docs/metadata | Delivered | see git log | 1/5, 20% |
| R2 — Tooling UI | Delivered | see git log | 2/5, 40% |
| R3 — Game boundary | Delivered | see git log | 3/5, 60% |
| R4 — Commands/configuration/deployment readiness | Delivered | see git log | 4/5, 80% |
| R5 — Integration/handoff/PR | Delivered; PR #2 open | see git log | 5/5, 100% |
External-operation ledger, separate from the five code-delivery milestones:
| Operation | Initial status |
|---|---|
GitHub repository rename to dusk-engine |
Done outside this pass: jasona/dusk-engine (old URL redirects). Local origin now points at [email protected]:jasona/dusk-engine.git. |
| Default branch change to main | Not performed; still codex/engine-foundations. |
| Coolify resource display/source changes | Not performed. Mapping in DUSK_COMPATIBILITY; existing DW_ settings keep working. Point the source at jasona/dusk-engine explicitly rather than relying on the redirect. |
| Production deployment of a Dusk build | Not performed. |
| Earlier externally run Docker acceptance | Awaiting the user's result for the exact tested commit. |
At each completed milestone, report:
Dusk rename: Rn delivered — n/5 (percentage).
Commit: <hash> on <branch>, pushed to <repository>.
Now available: <concrete user/developer outcome>.
Try it: <exact supported command and URL>.
Validation: <only checks actually completed, with their relevant scope>.
Visual: <actual screenshot for a visible change>.
Deferred/external: <specific remaining limits, if any>.
Next: <next fixed milestone, or stop after R5>.Final record:
- Dusk rename 5/5 (100%), with all mandatory criteria met.
- Feature inventory remains 70/70; earlier polish remains 5/5.
- Final branch/commit, PR link and actual merge status if separately authorized.
- Exact Dusk editor, Darkwind and Meridian run commands.
- Compatibility guarantees and intentional legacy identifiers.
- Actual configuration/storage continuity checks and visual captures.
- Exact external-operation, CI and Docker status; no inferred passes.
- A bounded list of deferred findings, followed by stop.