Roadmap: Introduce a context-isolated Nenjim process runtime #73

Open
opened 2026-08-15 14:17:54 +02:00 by minimons · 0 comments
Owner

Summary

NenjimHub currently constructs its components, plugins, services, and applications through hardcoded composition and then starts a hardcoded set of services and applications.

This is acceptable on the development machine, but it prevents safe server deployment. A headless server must be able to start production services such as the Ticker and Evelyn IOU Burner without starting graphical applications such as Evelyn Mission Control.

This roadmap introduces the core of the intended Nenjim runtime incrementally:

  • Explicit Nenjim contexts.
  • One context-specific classloader per context.
  • A canonical NenjimProcess lifecycle.
  • Context-bound access to components, plugins, and other processes.
  • Configuration-controlled process startup.
  • Gradual migration of existing services and applications.

Every implementation step will be handled by a separate child issue and a separate OpenSpec change. The repository must remain buildable and operational after every step.

This roadmap issue is a planning artifact and does not itself receive an OpenSpec change.

Motivation

The same codebase must support different deployments:

  • A server should start only the required production services.
  • A development machine should be able to start only the service or application currently being developed.
  • Test and production instances of the same process interface must remain distinct.
  • Graphical applications must not start on headless systems unless explicitly selected.
  • Existing critical production functionality must remain operational while newer code is migrated and validated.

The old production deployment currently protects real Jupiter Perps positions through alarms and automated adjustments. It must not be replaced prematurely by the newer development build.

The Evelyn IOU Burner uses a dedicated wallet and is non-critical. It can initially run through a separate, parallel NenjimHub deployment after the required runtime support is ready.

Architectural direction

Process identity

A process is identified by the combination:

Nenjim context + fully qualified process interface name

For example:

Production + com.fanitas.evelyn.core.Evelyn
Test       + com.fanitas.evelyn.core.Evelyn

These references represent different process instances even when they currently use the same implementation version.

Configuration must refer to process interfaces, not implementation classes or arbitrary global process names.

Canonical NenjimProcess lifecycle

Services and applications managed as independent runtime processes will expose an API interface extending the canonical NenjimProcess interface.

A Nenjim process implementation will:

  1. Provide a public default constructor.
  2. Be instantiated by its context-specific classloader.
  3. Receive a context-bound NenjimHub through setNenjimHub(...).
  4. Resolve and retain its dependencies through that Hub.
  5. Remain inactive until start() is called.

Conceptually:

Class<? extends NenjimProcess> processClass =
        contextClassLoader.resolve(processInterfaceName);

NenjimProcess process =
        processClass.getDeclaredConstructor().newInstance();

process.setNenjimHub(contextClassLoader.getNenjimHub());
process.start();

The exact APIs and package names will be defined in the relevant child issue.

The common process contract will not initially promise generic stop, restart, upgrade, or version-change operations.

Dependency resolution

Nenjim-managed processes will gradually move away from constructor injection.

During setNenjimHub(...), a process may request context-specific dependencies such as:

nenjimHub.getComponent(SomeComponent.class);
nenjimHub.getPlugins(SomePlugin.class);
nenjimHub.getProcess(SomeService.class);

The injected NenjimHub object will be bound to exactly one context. The process will not need to pass its context ID on every lookup.

The Hub must return dependencies belonging to the same context and classloader as the requesting process.

Ordinary internal implementation objects may still be created with normal Java expressions such as:

new InternalHelper();

Because the containing implementation class was defined by the context classloader, the referenced helper class will be resolved through the same context-specific loading rules.

Context-specific classloading

Each configured context will receive its own NenjimClassLoader.

The first implementation will use the same current code version in every context. It will not yet resolve multiple artifact versions.

Even when both contexts load identical class bytes, context-managed classes must be defined separately:

Production class identity = class name + Production classloader
Test class identity       = class name + Test classloader

The Nenjim kernel contracts required across the classloader boundary must be loaded by a shared parent classloader. Context-managed implementations must not first be loaded by the parent or system classloader.

The existing legacy classloader implementations may be used as design references, but they must not be assumed to be correct or operational.

Initialization versus startup

It remains acceptable for NenjimHub to initialize all known components, plugins, services, and applications required by the configured contexts.

Initialization must not begin active business processing.

In particular, initialization must not:

  • Start worker threads.
  • Begin price polling.
  • Monitor alarms.
  • Submit transactions.
  • Open graphical windows.
  • Bind network listeners intended for an active application.

Only NenjimProcess.start() activates a service or application.

Startup configuration

A versioned NenjimHub.conf file will define:

  • The available contexts.
  • The ordered list of processes to start.
  • The context associated with each process reference.

The exact grammar will be defined in a child issue. Conceptually, it will express entries similar to:

FORMAT_VERSION=1

[CONTEXTS]
Production
Test

[AUTO_START]
Production : com.r35157.assetaz.services.ticker.TickerService
Production : com.fanitas.evelyn.service.burner.EvelynIOUBurnerService

Startup order will follow configuration order.

Automatic dependency startup is not initially required. If the Burner requires an active Ticker, the configuration must list the Ticker before the Burner.

Configuration handling must be strict:

  • A missing required configuration file fails Hub startup.
  • An unsupported format version fails startup.
  • An unknown context fails startup.
  • An unknown process interface fails startup.
  • A duplicate process reference fails startup.
  • A process that does not implement NenjimProcess fails startup.
  • An empty autorun list is valid and starts no services or applications.
  • There must be no fallback that starts every known process.

Incremental implementation roadmap

The exact child-issue boundaries may be refined as implementation knowledge improves, but every child issue must remain independently implementable and archivable.

Runtime foundation

  • Define the canonical NenjimProcess, context, and classloader-boundary contracts in their final logical API packages.
  • Establish a minimal context runtime without changing existing production startup behavior.
  • Implement one real context classloader per context while loading the same current code version.
  • Demonstrate that identical class names loaded through different contexts have different Java class identities.
  • Instantiate a simple process through its public default constructor.
  • Supply a context-bound NenjimHub and invoke the process lifecycle in the required order.

Context dependency resolution

  • Define context-bound component lookup.
  • Define ordered plugin lookup.
  • Define lookup of another process within the same context.
  • Ensure returned objects belong to the requesting context and are type-compatible with its classloader.
  • Define strict behavior for missing, ambiguous, or invalid bindings.
  • Keep all dependency bindings hardcoded initially; dynamic journals and artifact resolution remain deferred.

NenjimHub configuration

  • Define the versioned NenjimHub.conf grammar.
  • Parse and validate context definitions.
  • Parse and validate ordered autorun process references.
  • Preserve configuration order during startup.
  • Ensure that unselected processes remain initialized but unstarted.
  • Fail safely instead of falling back to starting every process.

Process migrations

Processes will be migrated individually. Each migration must leave the process fully functional and remove its corresponding legacy construction and startup path atomically.

  • Migrate TickerService.
  • Make TickerService obtain its PriceSource plugins from its context-bound Hub.
  • Migrate the Production and Test Evelyn service instances.
  • Demonstrate that the same Evelyn process interface produces distinct context-owned instances.
  • Migrate EvelynIOUBurnerService.
  • Move Burner dependencies to context resolution and its operational values to an appropriate service configuration.
  • Migrate Evelyn Mission Control.
  • Confirm that Mission Control is initialized but opens no JavaFX window unless explicitly started.
  • Switch the current development Hub from hardcoded startup to the ordered autorun configuration.
  • Migrate remaining non-critical services and applications incrementally.
  • Migrate Jupiter Perps alarms and related critical processes only after the new runtime has been validated independently.

Parallel production validation

  • Keep the existing proven production deployment unchanged for Jupiter Perps and alarm protection.
  • Deploy the newer NenjimHub as a separate process with a configuration that starts only the required Ticker and Burner processes.
  • Use separate working directories, configuration files, logs, mutable data paths, and network ports where applicable.
  • Ensure that the two deployments never actively use the same signer wallet.
  • Observe the new runtime independently before migrating any critical Perps functionality.
  • Return to a single production deployment only after the migrated Perps and alarm paths are trusted.

Legacy cleanup

Cleanup must happen only after the replacement behavior is operational.

  • Remove obsolete duplicate NenjimProcess contracts.
  • Remove obsolete classloader and kicker implementations after useful ideas have been preserved.
  • Remove hardcoded process startup from NenjimHubImpl.
  • Remove legacy construction paths as each process migration completes.
  • Preserve or clearly identify dormant prototype code that remains useful as architectural reference.

NenjimTestTool follow-up

NenjimTestTool is a later roadmap track and is not part of the initial runtime migration.

The existing code contains:

  • A legacy JavaFX prototype under crypto.r35157.nenjim.NenjimTestTool.
  • A newer but mostly empty API and reference implementation under com.r35157.nenjim.ntt.

The legacy implementation contains useful ideas for selecting test artifacts, loading test classes, and executing discovered tests. It must remain available as reference until a replacement has preserved those ideas.

Later work should enable NenjimTestTool to:

  • Create a dedicated test context.
  • Bind API, implementation, and test artifacts.
  • Load them through the context runtime.
  • Execute one reusable test artifact against different implementations.
  • Present discovery, execution, and results through its GUI.

Broad implementation unit tests remain deferred until the test-artifact and NenjimTestTool architecture is sufficiently stable. Any focused automated verification introduced for the classloader kernel must be explicitly approved by its child issue.

OpenSpec workflow

This roadmap does not receive one large, long-lived OpenSpec change.

For every implementation child issue:

  1. Create one narrowly scoped OpenSpec change.
  2. Describe only the behavior delivered by that child issue.
  3. Keep future roadmap behavior out of its canonical requirements.
  4. Implement and validate the change.
  5. Synchronize its delta specifications.
  6. Archive it before beginning a dependent change affecting the same specifications.
  7. Update this roadmap checklist and link the completed child issue.

Canonical OpenSpec specifications must describe currently implemented guarantees, not unimplemented roadmap intentions.

Non-goals for the initial migration

The initial context runtime does not need to support:

  • Different module versions in different contexts.
  • Journal-based version recommendations.
  • Artifact download or installation.
  • Runtime process stop or restart.
  • Hot reload.
  • Changing a process version while running.
  • Dynamic creation of new dependency graphs after Hub startup.
  • Automatic startup of process dependencies.
  • Unloading contexts or guaranteeing classloader garbage collection.
  • Migrating every service and application in one change.
  • Replacing the existing critical production deployment immediately.
  • Completing NenjimTestTool or the general test-artifact system.

These capabilities may be introduced by later roadmaps after the context runtime has proved stable.

Completion criteria

This roadmap is complete when:

  • Production and Test can use separate context classloaders.
  • The same process interface can produce independent context-owned instances.
  • Processes use public default constructors and receive a context-bound Hub before startup.
  • Components, plugins, and processes are resolved within the correct context.
  • NenjimHub.conf controls exactly which processes are started and in which order.
  • A headless server can run Ticker and Burner without starting graphical applications.
  • Development configurations can start only the processes required for current work.
  • Critical Perps and alarm functionality has been migrated and validated without an unsafe cutover.
  • Legacy hardcoded startup and obsolete competing Nenjim runtime paths have been removed.
  • Every completed implementation increment is represented by synchronized and archived OpenSpec changes.
## Summary NenjimHub currently constructs its components, plugins, services, and applications through hardcoded composition and then starts a hardcoded set of services and applications. This is acceptable on the development machine, but it prevents safe server deployment. A headless server must be able to start production services such as the Ticker and Evelyn IOU Burner without starting graphical applications such as Evelyn Mission Control. This roadmap introduces the core of the intended Nenjim runtime incrementally: * Explicit Nenjim contexts. * One context-specific classloader per context. * A canonical `NenjimProcess` lifecycle. * Context-bound access to components, plugins, and other processes. * Configuration-controlled process startup. * Gradual migration of existing services and applications. Every implementation step will be handled by a separate child issue and a separate OpenSpec change. The repository must remain buildable and operational after every step. This roadmap issue is a planning artifact and does not itself receive an OpenSpec change. ## Motivation The same codebase must support different deployments: * A server should start only the required production services. * A development machine should be able to start only the service or application currently being developed. * Test and production instances of the same process interface must remain distinct. * Graphical applications must not start on headless systems unless explicitly selected. * Existing critical production functionality must remain operational while newer code is migrated and validated. The old production deployment currently protects real Jupiter Perps positions through alarms and automated adjustments. It must not be replaced prematurely by the newer development build. The Evelyn IOU Burner uses a dedicated wallet and is non-critical. It can initially run through a separate, parallel NenjimHub deployment after the required runtime support is ready. ## Architectural direction ### Process identity A process is identified by the combination: ```text Nenjim context + fully qualified process interface name ``` For example: ```text Production + com.fanitas.evelyn.core.Evelyn Test + com.fanitas.evelyn.core.Evelyn ``` These references represent different process instances even when they currently use the same implementation version. Configuration must refer to process interfaces, not implementation classes or arbitrary global process names. ### Canonical NenjimProcess lifecycle Services and applications managed as independent runtime processes will expose an API interface extending the canonical `NenjimProcess` interface. A Nenjim process implementation will: 1. Provide a public default constructor. 2. Be instantiated by its context-specific classloader. 3. Receive a context-bound `NenjimHub` through `setNenjimHub(...)`. 4. Resolve and retain its dependencies through that Hub. 5. Remain inactive until `start()` is called. Conceptually: ```java Class<? extends NenjimProcess> processClass = contextClassLoader.resolve(processInterfaceName); NenjimProcess process = processClass.getDeclaredConstructor().newInstance(); process.setNenjimHub(contextClassLoader.getNenjimHub()); process.start(); ``` The exact APIs and package names will be defined in the relevant child issue. The common process contract will not initially promise generic stop, restart, upgrade, or version-change operations. ### Dependency resolution Nenjim-managed processes will gradually move away from constructor injection. During `setNenjimHub(...)`, a process may request context-specific dependencies such as: ```java nenjimHub.getComponent(SomeComponent.class); nenjimHub.getPlugins(SomePlugin.class); nenjimHub.getProcess(SomeService.class); ``` The injected `NenjimHub` object will be bound to exactly one context. The process will not need to pass its context ID on every lookup. The Hub must return dependencies belonging to the same context and classloader as the requesting process. Ordinary internal implementation objects may still be created with normal Java expressions such as: ```java new InternalHelper(); ``` Because the containing implementation class was defined by the context classloader, the referenced helper class will be resolved through the same context-specific loading rules. ### Context-specific classloading Each configured context will receive its own `NenjimClassLoader`. The first implementation will use the same current code version in every context. It will not yet resolve multiple artifact versions. Even when both contexts load identical class bytes, context-managed classes must be defined separately: ```text Production class identity = class name + Production classloader Test class identity = class name + Test classloader ``` The Nenjim kernel contracts required across the classloader boundary must be loaded by a shared parent classloader. Context-managed implementations must not first be loaded by the parent or system classloader. The existing legacy classloader implementations may be used as design references, but they must not be assumed to be correct or operational. ### Initialization versus startup It remains acceptable for NenjimHub to initialize all known components, plugins, services, and applications required by the configured contexts. Initialization must not begin active business processing. In particular, initialization must not: * Start worker threads. * Begin price polling. * Monitor alarms. * Submit transactions. * Open graphical windows. * Bind network listeners intended for an active application. Only `NenjimProcess.start()` activates a service or application. ### Startup configuration A versioned `NenjimHub.conf` file will define: * The available contexts. * The ordered list of processes to start. * The context associated with each process reference. The exact grammar will be defined in a child issue. Conceptually, it will express entries similar to: ```text FORMAT_VERSION=1 [CONTEXTS] Production Test [AUTO_START] Production : com.r35157.assetaz.services.ticker.TickerService Production : com.fanitas.evelyn.service.burner.EvelynIOUBurnerService ``` Startup order will follow configuration order. Automatic dependency startup is not initially required. If the Burner requires an active Ticker, the configuration must list the Ticker before the Burner. Configuration handling must be strict: * A missing required configuration file fails Hub startup. * An unsupported format version fails startup. * An unknown context fails startup. * An unknown process interface fails startup. * A duplicate process reference fails startup. * A process that does not implement `NenjimProcess` fails startup. * An empty autorun list is valid and starts no services or applications. * There must be no fallback that starts every known process. ## Incremental implementation roadmap The exact child-issue boundaries may be refined as implementation knowledge improves, but every child issue must remain independently implementable and archivable. ### Runtime foundation * [ ] Define the canonical `NenjimProcess`, context, and classloader-boundary contracts in their final logical API packages. * [ ] Establish a minimal context runtime without changing existing production startup behavior. * [ ] Implement one real context classloader per context while loading the same current code version. * [ ] Demonstrate that identical class names loaded through different contexts have different Java class identities. * [ ] Instantiate a simple process through its public default constructor. * [ ] Supply a context-bound `NenjimHub` and invoke the process lifecycle in the required order. ### Context dependency resolution * [ ] Define context-bound component lookup. * [ ] Define ordered plugin lookup. * [ ] Define lookup of another process within the same context. * [ ] Ensure returned objects belong to the requesting context and are type-compatible with its classloader. * [ ] Define strict behavior for missing, ambiguous, or invalid bindings. * [ ] Keep all dependency bindings hardcoded initially; dynamic journals and artifact resolution remain deferred. ### NenjimHub configuration * [ ] Define the versioned `NenjimHub.conf` grammar. * [ ] Parse and validate context definitions. * [ ] Parse and validate ordered autorun process references. * [ ] Preserve configuration order during startup. * [ ] Ensure that unselected processes remain initialized but unstarted. * [ ] Fail safely instead of falling back to starting every process. ### Process migrations Processes will be migrated individually. Each migration must leave the process fully functional and remove its corresponding legacy construction and startup path atomically. * [ ] Migrate `TickerService`. * [ ] Make `TickerService` obtain its `PriceSource` plugins from its context-bound Hub. * [ ] Migrate the Production and Test Evelyn service instances. * [ ] Demonstrate that the same Evelyn process interface produces distinct context-owned instances. * [ ] Migrate `EvelynIOUBurnerService`. * [ ] Move Burner dependencies to context resolution and its operational values to an appropriate service configuration. * [ ] Migrate Evelyn Mission Control. * [ ] Confirm that Mission Control is initialized but opens no JavaFX window unless explicitly started. * [ ] Switch the current development Hub from hardcoded startup to the ordered autorun configuration. * [ ] Migrate remaining non-critical services and applications incrementally. * [ ] Migrate Jupiter Perps alarms and related critical processes only after the new runtime has been validated independently. ### Parallel production validation * [ ] Keep the existing proven production deployment unchanged for Jupiter Perps and alarm protection. * [ ] Deploy the newer NenjimHub as a separate process with a configuration that starts only the required Ticker and Burner processes. * [ ] Use separate working directories, configuration files, logs, mutable data paths, and network ports where applicable. * [ ] Ensure that the two deployments never actively use the same signer wallet. * [ ] Observe the new runtime independently before migrating any critical Perps functionality. * [ ] Return to a single production deployment only after the migrated Perps and alarm paths are trusted. ### Legacy cleanup Cleanup must happen only after the replacement behavior is operational. * [ ] Remove obsolete duplicate `NenjimProcess` contracts. * [ ] Remove obsolete classloader and kicker implementations after useful ideas have been preserved. * [ ] Remove hardcoded process startup from `NenjimHubImpl`. * [ ] Remove legacy construction paths as each process migration completes. * [ ] Preserve or clearly identify dormant prototype code that remains useful as architectural reference. ### NenjimTestTool follow-up NenjimTestTool is a later roadmap track and is not part of the initial runtime migration. The existing code contains: * A legacy JavaFX prototype under `crypto.r35157.nenjim.NenjimTestTool`. * A newer but mostly empty API and reference implementation under `com.r35157.nenjim.ntt`. The legacy implementation contains useful ideas for selecting test artifacts, loading test classes, and executing discovered tests. It must remain available as reference until a replacement has preserved those ideas. Later work should enable NenjimTestTool to: * Create a dedicated test context. * Bind API, implementation, and test artifacts. * Load them through the context runtime. * Execute one reusable test artifact against different implementations. * Present discovery, execution, and results through its GUI. Broad implementation unit tests remain deferred until the test-artifact and NenjimTestTool architecture is sufficiently stable. Any focused automated verification introduced for the classloader kernel must be explicitly approved by its child issue. ## OpenSpec workflow This roadmap does not receive one large, long-lived OpenSpec change. For every implementation child issue: 1. Create one narrowly scoped OpenSpec change. 2. Describe only the behavior delivered by that child issue. 3. Keep future roadmap behavior out of its canonical requirements. 4. Implement and validate the change. 5. Synchronize its delta specifications. 6. Archive it before beginning a dependent change affecting the same specifications. 7. Update this roadmap checklist and link the completed child issue. Canonical OpenSpec specifications must describe currently implemented guarantees, not unimplemented roadmap intentions. ## Non-goals for the initial migration The initial context runtime does not need to support: * Different module versions in different contexts. * Journal-based version recommendations. * Artifact download or installation. * Runtime process stop or restart. * Hot reload. * Changing a process version while running. * Dynamic creation of new dependency graphs after Hub startup. * Automatic startup of process dependencies. * Unloading contexts or guaranteeing classloader garbage collection. * Migrating every service and application in one change. * Replacing the existing critical production deployment immediately. * Completing NenjimTestTool or the general test-artifact system. These capabilities may be introduced by later roadmaps after the context runtime has proved stable. ## Completion criteria This roadmap is complete when: * Production and Test can use separate context classloaders. * The same process interface can produce independent context-owned instances. * Processes use public default constructors and receive a context-bound Hub before startup. * Components, plugins, and processes are resolved within the correct context. * `NenjimHub.conf` controls exactly which processes are started and in which order. * A headless server can run Ticker and Burner without starting graphical applications. * Development configurations can start only the processes required for current work. * Critical Perps and alarm functionality has been migrated and validated without an unsafe cutover. * Legacy hardcoded startup and obsolete competing Nenjim runtime paths have been removed. * Every completed implementation increment is represented by synchronized and archived OpenSpec changes.
minimons added the enhancement label 2026-08-15 14:17:54 +02:00
minimons self-assigned this 2026-08-15 14:17:54 +02:00
minimons added this to the AssetAZ project 2026-08-15 14:17:54 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: r35157/com_r35157_nenjim-hubd-impl_ref#73