This prevents the same build from supporting different deployment roles.
For example, a headless server should be able to omit JavaFX, Mission Control and Process Manager.
Nenjim does not yet have automatic process-dependency resolution. Until that functionality exists, configuration must contain the complete ordered set of processes required by the deployment.
Goal
Introduce the first mandatory NenjimHub.conf format, identified by format version 1, containing an ordered [AUTO_START] section.
The Hub shall:
Read and validate the configuration before beginning process startup.
Bootstrap the configured Registry process.
Construct and register the complete current passive component graph.
Construct, register and start only the remaining NenjimProcess objects explicitly listed in [AUTO_START].
Preserve configuration order exactly.
Keep process construction and startup fail-fast.
Remove the existing hardcoded process construction and startup list.
A process omitted from [AUTO_START] shall not be constructed, registered or started.
Current transitional model
This issue deliberately implements a transitional runtime model.
All current passive building blocks are constructed eagerly because Nenjim does not yet resolve component dependencies automatically.
Process objects are different:
A passive component is constructed and registered independently of [AUTO_START].
A NenjimProcess object is constructed only when its component ID appears in [AUTO_START].
The selected process is registered before its start() operation is invoked.
A process omitted from [AUTO_START] does not exist in the runtime object graph or Registry.
A service or application role does not by itself determine construction behaviour. The technical distinction is whether the implementation participates in the Hub-managed lifecycle through the canonical NenjimProcess interface.
The Registry process is the necessary bootstrap exception: it must be constructed and started before other components can be registered.
Future dependency model
The intended future model is top-down recursive dependency construction.
When a process is requested in the future, Nenjim may:
Resolve the requested process.
Discover its component and process dependencies.
Resolve those dependencies recursively.
Construct the resulting graph from its leaves.
Start processes in dependency-safe order.
That functionality does not exist yet.
For format 1, [AUTO_START] is therefore the complete manually ordered process closure required by the deployment. The Hub shall not infer dependencies, insert missing processes, reorder entries, or start processes recursively.
If a selected process requires another process object through the current constructor wiring, that dependency must have been selected and constructed earlier in [AUTO_START].
A missing predecessor shall produce a clear fail-fast construction or startup failure. It shall not cause implicit process construction.
Configuration location
The runtime configuration path shall be fixed as:
conf/NenjimHub.conf
Main shall continue to construct and start the reference Hub normally. No command-line configuration-path option is introduced.
The Hub shall read only conf/NenjimHub.conf.
The repository shall contain:
conf/NenjimHub.conf.example
The example file exists only as a generic template that an operator can copy and edit.
The application shall never:
Read conf/NenjimHub.conf.example.
Fall back to the example file.
Copy the example automatically.
Generate a runtime configuration.
Fall back to the former hardcoded startup list.
The real conf/NenjimHub.conf remains deployment-specific and excluded from Git by the existing ignore rules.
A missing, unreadable or non-regular runtime configuration file shall fail Hub startup clearly before any process is started.
Format version
Adding a mandatory runtime configuration is a breaking deployment change. However, because NenjimHub.conf did not previously exist, this is the first version of this configuration format.
The configuration shall therefore require:
FORMAT_VERSION=1
Version 1 is the only supported version for this issue.
FORMAT_VERSION=1 shall be the first actual configuration entry. Leading blank lines and full-line comments may precede it.
Any value other than FORMAT_VERSION=1, as well as missing, malformed or duplicate version declarations, shall fail clearly.
Each entry in [AUTO_START] is one NenjimComponentId.
The section order is the requested process construction and startup order.
Operators add their own deployment-specific process IDs and dependencies after copying the example to conf/NenjimHub.conf.
Comments and whitespace
The parser shall support blank lines and # comments consistently.
Outside [AUTO_START]:
Leading and trailing whitespace shall be ignored.
Blank lines shall be accepted.
A line whose trimmed content starts with # shall be treated as a full-line comment.
A # after actual content shall begin a trailing comment.
Comment text shall be ignored.
Inside [AUTO_START]:
Leading and trailing whitespace around a process ID shall be ignored.
A line whose trimmed content starts with # shall be ignored as a comment and shall not terminate the section.
A # after a process ID shall begin a trailing comment.
The process ID before a trailing comment shall be trimmed and parsed normally.
A whitespace-only line shall terminate [AUTO_START].
End of file shall also terminate [AUTO_START].
Comment processing shall distinguish comment-only lines from empty terminating lines. A comment-only line inside the section shall not end the section.
There is no quoting or escaping mechanism for # in format 1 because # is not valid within a NenjimComponentId.
After [AUTO_START] has terminated, only blank lines and comments are permitted. Any further actual entry or section shall fail as unexpected content.
Section rules
Format 1 shall contain exactly one [AUTO_START] section.
The section header shall:
Be spelled exactly [AUTO_START].
Be the first actual entry after FORMAT_VERSION=1.
Appear exactly once.
Not contain a value or trailing tokens other than an optional comment.
Unknown sections, duplicate [AUTO_START] sections, entries before the section and malformed section headers shall fail clearly.
An immediately terminated or otherwise empty [AUTO_START] section is invalid because Registry and Journal are mandatory.
Process-ID validation
Each active line in [AUTO_START] shall be parsed as a NenjimComponentId using the existing component-ID rules.
The complete list shall be validated before the first process is started.
Validation shall reject:
Invalid component-ID syntax.
Duplicate process IDs.
Unknown process IDs.
IDs known only as passive components.
IDs which the current Hub cannot construct as a canonical NenjimProcess.
A missing Registry entry.
A missing Journal entry.
Registry anywhere other than the first position.
Journal anywhere other than the second position.
Failures shall identify the configuration path, relevant line when applicable, offending value and reason.
No invalid configuration shall fall back to the previous hardcoded startup behaviour.
Mandatory bootstrap order
Every valid format 1 configuration shall begin with:
nenjim.registry.service
nenjim.journal.service
The Registry shall appear exactly once and as the first process.
The Journal shall appear exactly once and as the second process.
The configured order represents process order, while Registry bootstrap necessarily surrounds passive component construction.
The Hub shall perform startup in these phases:
Parse and validate the complete configuration.
Construct the configured Registry subsystem.
Start the Registry process.
Register the Registry service as nenjim.registry.service.
Record the successful Registry startup.
Construct and register the complete current passive component graph.
Process the remaining [AUTO_START] entries in their declared order, beginning with Journal.
Announce the existing online point only after every configured process has started successfully.
Enter the existing blocking runtime wait.
Journal shall therefore remain the second started process, even though passive component construction occurs between successful Registry startup and Journal construction.
Passive component construction
After successful Registry startup, the Hub shall eagerly construct and register the current non-process dependency graph required to construct selectable processes.
This includes the existing passive building blocks, adapters and services which do not implement the canonical NenjimProcess.
The existing component IDs and dependency wiring shall remain unchanged unless a change is strictly required to separate passive construction from selected process construction.
Passive construction shall not:
Start background workers.
Open JavaFX windows.
Activate a NenjimProcess.
Add an ID to the Hub's started-process snapshot.
Automatically construct an omitted process.
Infer process dependencies from constructors or interfaces.
Plain internal dependencies which are not NenjimComponent objects may still be constructed by the Hub as part of the passive object graph.
Lazy process construction
The Hub shall maintain an implementation-only catalogue of the modern process IDs it knows how to construct, or equivalent internal lazy-construction logic.
The catalogue shall describe construction capability without constructing process instances during configuration validation.
No new public process-factory, registration or discovery API shall be introduced.
For each [AUTO_START] entry after Registry, the Hub shall:
Select the known internal constructor for the exact configured NenjimComponentId.
Construct the process and any process-specific passive administration view required by its subsystem.
Register the constructed process under the configured ID.
Resolve the registered object through the canonical NenjimProcess contract where applicable.
Invoke start().
Record the ID only after start() returns successfully.
Continue to the next configured entry.
A process shall not be constructed speculatively before its entry is reached.
A construction failure shall leave the process unregistered.
A startup failure may leave the already constructed process registered, matching the existing registration-before-start lifecycle. Its ID shall not be added to the started-process snapshot.
Known selectable processes
The format 1 implementation shall support lazy construction of the modern processes currently known by the active Hub:
The version-controlled example shall contain only Registry and Journal. Every optional process, including Jupiter Perps Alarm, shall remain absent until an operator explicitly adds it to the private deployment configuration.
Legacy process prototypes outside the modern Hub component graph shall not become selectable merely because they exist in the repository.
Adding general process discovery is outside this issue.
Dependency-sensitive examples
The Hub shall preserve configuration order without deriving a dependency graph.
For example, a deployment selecting JavaFX applications must place the JavaFX runtime before those applications.
The Hub does not need a general rule identifying JavaFX applications. Existing JavaFX consumers already reject use of an inactive JavaFxRuntimeService.
Likewise, if a selected application currently requires another selected service instance during construction, the configuration must place that service first.
The Hub shall not automatically repair an invalid operational order.
Default example configuration
Create or update:
conf/NenjimHub.conf.example
with a documented, generic format 1 example containing only the mandatory Registry and Journal bootstrap entries:
# Copy this template to conf/NenjimHub.conf before starting Nenjim Hub.
# Registry and Journal are mandatory and must be the first two entries.
# Entries are ordered. List every process dependency manually before its consumers.
FORMAT_VERSION=1
[AUTO_START]
nenjim.registry.service
nenjim.journal.service
The example shall explain through comments that:
The file must be copied to conf/NenjimHub.conf before use.
Registry and Journal are mandatory.
Entries are ordered.
Process dependencies must currently be listed manually before their consumers.
The example shall not contain optional deployment-specific process IDs.
The example itself shall not be loaded by the application.
Headless configuration
Documentation shall include the same minimal headless bootstrap:
This configuration shall construct and start only the mandatory Registry and Journal processes. It shall not construct, register or start any optional process.
The JavaFX runtime shall not be initialized merely because JavaFX-capable implementation classes exist in the repository.
Failure semantics
Configuration and startup remain fail-fast.
Before Registry startup, the Hub shall reject all configuration errors that can be determined from:
File access.
Format syntax.
Format version.
Section structure.
Component-ID syntax.
Duplicate IDs.
The Hub's known process-construction catalogue.
Mandatory Registry and Journal placement.
After Registry startup:
Passive component construction failure stops startup.
Selected process construction failure stops startup.
Selected process registration failure stops startup.
Selected process startup failure stops startup.
No later configured process is constructed or started.
The online point is not announced.
This issue shall not introduce general rollback.
Processes which started successfully before a later failure remain represented in the Hub's immutable point-in-time started-process snapshots.
A failing process is never recorded as successfully started.
Process Manager behaviour
No Process Manager API or polling change is required.
When selected, Nenjim Process Manager continues to poll:
NenjimHub.getStartedProcessIds()
It shall therefore display only processes whose startup completed successfully.
Its list shall not be populated from AUTO_START directly.
When Process Manager is omitted from [AUTO_START], it is not constructed, registered or started.
Hub API
No new public operation shall be added to NenjimHub.
The exact [AUTO_START] grammar and termination rule.
Comment and whitespace handling.
Strict configuration validation.
Registry and Journal as mandatory first and second entries.
Eager passive component construction after Registry startup.
Lazy construction of selected process objects.
Registration-before-start behaviour.
Exact ordered startup.
Omitted-process behaviour.
Failure and partial-startup semantics.
The example file's generic, template-only role.
Removal of the hardcoded startup path.
The temporary manual process-dependency model.
Introduce a focused Hub configuration capability and update only other canonical specifications whose currently implemented guarantees change.
Keep the OpenSpec change active after implementation until the implementation has been reviewed and accepted. After acceptance, synchronize its delta specifications into the main specifications and archive the change.
Scope
This issue includes:
Adding strict format 1 NenjimHub.conf parsing.
Adding the mandatory ordered [AUTO_START] section.
Using NenjimComponentId entries.
Supporting full-line and trailing # comments.
Ending [AUTO_START] at the first trimmed empty line or end of file.
Requiring Registry first and Journal second.
Validating the complete known process list before Registry startup.
Starting Registry before passive component construction.
Constructing and registering all current passive components.
Lazily constructing, registering and starting selected processes.
Supporting all modern process IDs currently known by the Hub.
Preserving configured process order.
Preserving fail-fast startup and truthful started-process snapshots.
Adding or updating the generic conf/NenjimHub.conf.example.
Documenting minimal headless configuration.
Removing unconditional process construction and hardcoded startup.
Building the complete repository successfully.
Out of scope
This issue does not implement:
Automatic dependency discovery.
Recursive dependency construction.
Automatic dependency startup.
Startup-order calculation.
Reordering or repairing configuration.
Context definitions.
Context resolution.
Artifact-version selection.
Implementation-version selection.
Journal-driven process resolution.
Classloader changes.
Dynamic process discovery.
Public process-factory registration.
Runtime process construction after Hub startup.
Process stop or restart.
Startup rollback.
Health monitoring.
Recovery or supervision.
Hub lifecycle events.
Event subscriptions.
Configuration reload.
Runtime configuration editing.
Command-line configuration-path selection.
Loading or copying the example configuration.
General unit tests.
NenjimTestTool functionality.
Production deployment automation.
Acceptance criteria
Hub startup reads only conf/NenjimHub.conf.
A missing, unreadable or non-regular runtime configuration fails startup clearly.
conf/NenjimHub.conf.example is never used as runtime input.
FORMAT_VERSION=1 is required as the first actual entry.
Any format version other than 1 is rejected.
Exactly one [AUTO_START] section is required.
Each active section entry is parsed as a NenjimComponentId.
Leading and trailing whitespace is handled as specified.
Full-line # comments are supported.
Trailing # comments are supported.
Comment-only lines inside [AUTO_START] do not terminate it.
The first trimmed empty line terminates [AUTO_START].
End of file may terminate [AUTO_START].
Only blank lines and comments are accepted after section termination.
Duplicate process IDs are rejected.
Unknown process IDs are rejected before process startup.
Passive component IDs in [AUTO_START] are rejected.
Registry is required exactly once as the first process.
Journal is required exactly once as the second process.
Registry starts before passive component construction.
The complete current passive component graph is constructed and registered after Registry startup.
Passive component construction starts no NenjimProcess.
Journal is the second successfully started process.
Each remaining process is constructed only when its configured entry is reached.
A selected process is registered before its start() operation.
A successfully started process is recorded after start() returns.
A failing process is not recorded as successfully started.
A process omitted from [AUTO_START] is not constructed.
A process omitted from [AUTO_START] is not registered.
A process omitted from [AUTO_START] is not started.
Configured process order is preserved exactly.
Missing process dependencies are not constructed automatically.
The Hub does not infer or reorder process dependencies.
Startup stops at the first passive-construction, process-construction, registration or process-start failure.
No general rollback is introduced.
The online point is announced only after every configured process has started successfully.
The current modern process IDs, including the optional Jupiter Perps Alarm, are selectable.
The example configuration contains only the mandatory Registry and Journal entries.
The example configuration contains no optional deployment-specific process IDs.
A headless configuration can omit JavaFX runtime, Mission Control and Process Manager.
Omitting all JavaFX processes leaves the JavaFX toolkit uninitialized.
Process Manager continues to display actual successful startup snapshots rather than configured intent.
The former hardcoded process construction and startup path is removed.
No fallback starts every known process.
No Context, version resolution, recursive dependency startup, events, stop lifecycle or health monitoring is added.
No general unit tests or NenjimTestTool functionality are added.
Relevant documentation describes only the implemented format 1 behaviour.
The repository builds successfully.
The OpenSpec change describes only the functionality delivered by this issue.
The OpenSpec delta specifications are synchronized and the accepted change is archived.
## Background
Issues #77 through #80 established the current Nenjim runtime model:
- `NenjimHub` owns the object graph and process lifecycle.
- The Registry contains constructed components.
- Active components implement the canonical `NenjimProcess`.
- The Hub records successfully started process IDs.
- Nenjim Process Manager displays the Hub's started-process snapshot.
- The shared JavaFX runtime is an explicit Hub-managed process.
- Process startup remains hardcoded in `NenjimHubImpl`.
The current Hub always constructs all process objects and then starts this fixed sequence:
```text
nenjim.registry.service
nenjim.journal.service
assetaz.ticker.default
evelyn.service.prod
evelyn.service.test
evelyn.iou-burner.prod
nenjim.javafx-runtime.service
evelyn.mission-control.default
nenjim.process-manager.default
```
This prevents the same build from supporting different deployment roles.
For example, a headless server should be able to omit JavaFX, Mission Control and Process Manager.
Nenjim does not yet have automatic process-dependency resolution. Until that functionality exists, configuration must contain the complete ordered set of processes required by the deployment.
## Goal
Introduce the first mandatory `NenjimHub.conf` format, identified by format version 1, containing an ordered `[AUTO_START]` section.
The Hub shall:
1. Read and validate the configuration before beginning process startup.
2. Bootstrap the configured Registry process.
3. Construct and register the complete current passive component graph.
4. Construct, register and start only the remaining `NenjimProcess` objects explicitly listed in `[AUTO_START]`.
5. Preserve configuration order exactly.
6. Keep process construction and startup fail-fast.
7. Remove the existing hardcoded process construction and startup list.
A process omitted from `[AUTO_START]` shall not be constructed, registered or started.
## Current transitional model
This issue deliberately implements a transitional runtime model.
All current passive building blocks are constructed eagerly because Nenjim does not yet resolve component dependencies automatically.
Process objects are different:
- A passive component is constructed and registered independently of `[AUTO_START]`.
- A `NenjimProcess` object is constructed only when its component ID appears in `[AUTO_START]`.
- The selected process is registered before its `start()` operation is invoked.
- A process omitted from `[AUTO_START]` does not exist in the runtime object graph or Registry.
A service or application role does not by itself determine construction behaviour. The technical distinction is whether the implementation participates in the Hub-managed lifecycle through the canonical `NenjimProcess` interface.
The Registry process is the necessary bootstrap exception: it must be constructed and started before other components can be registered.
## Future dependency model
The intended future model is top-down recursive dependency construction.
When a process is requested in the future, Nenjim may:
1. Resolve the requested process.
2. Discover its component and process dependencies.
3. Resolve those dependencies recursively.
4. Construct the resulting graph from its leaves.
5. Start processes in dependency-safe order.
That functionality does not exist yet.
For format 1, `[AUTO_START]` is therefore the complete manually ordered process closure required by the deployment. The Hub shall not infer dependencies, insert missing processes, reorder entries, or start processes recursively.
If a selected process requires another process object through the current constructor wiring, that dependency must have been selected and constructed earlier in `[AUTO_START]`.
A missing predecessor shall produce a clear fail-fast construction or startup failure. It shall not cause implicit process construction.
## Configuration location
The runtime configuration path shall be fixed as:
```text
conf/NenjimHub.conf
```
`Main` shall continue to construct and start the reference Hub normally. No command-line configuration-path option is introduced.
The Hub shall read only `conf/NenjimHub.conf`.
The repository shall contain:
```text
conf/NenjimHub.conf.example
```
The example file exists only as a generic template that an operator can copy and edit.
The application shall never:
- Read `conf/NenjimHub.conf.example`.
- Fall back to the example file.
- Copy the example automatically.
- Generate a runtime configuration.
- Fall back to the former hardcoded startup list.
The real `conf/NenjimHub.conf` remains deployment-specific and excluded from Git by the existing ignore rules.
A missing, unreadable or non-regular runtime configuration file shall fail Hub startup clearly before any process is started.
## Format version
Adding a mandatory runtime configuration is a breaking deployment change. However, because `NenjimHub.conf` did not previously exist, this is the first version of this configuration format.
The configuration shall therefore require:
```text
FORMAT_VERSION=1
```
Version 1 is the only supported version for this issue.
`FORMAT_VERSION=1` shall be the first actual configuration entry. Leading blank lines and full-line comments may precede it.
Any value other than FORMAT_VERSION=1, as well as missing, malformed or duplicate version declarations, shall fail clearly.
## Text format
A minimal generic configuration is:
```text
FORMAT_VERSION=1
[AUTO_START]
nenjim.registry.service
nenjim.journal.service
```
Each entry in `[AUTO_START]` is one `NenjimComponentId`.
The section order is the requested process construction and startup order.
Operators add their own deployment-specific process IDs and dependencies after copying the example to `conf/NenjimHub.conf`.
## Comments and whitespace
The parser shall support blank lines and `#` comments consistently.
Outside `[AUTO_START]`:
- Leading and trailing whitespace shall be ignored.
- Blank lines shall be accepted.
- A line whose trimmed content starts with `#` shall be treated as a full-line comment.
- A `#` after actual content shall begin a trailing comment.
- Comment text shall be ignored.
Inside `[AUTO_START]`:
- Leading and trailing whitespace around a process ID shall be ignored.
- A line whose trimmed content starts with `#` shall be ignored as a comment and shall not terminate the section.
- A `#` after a process ID shall begin a trailing comment.
- The process ID before a trailing comment shall be trimmed and parsed normally.
- A whitespace-only line shall terminate `[AUTO_START]`.
- End of file shall also terminate `[AUTO_START]`.
Comment processing shall distinguish comment-only lines from empty terminating lines. A comment-only line inside the section shall not end the section.
There is no quoting or escaping mechanism for `#` in format 1 because `#` is not valid within a `NenjimComponentId`.
After `[AUTO_START]` has terminated, only blank lines and comments are permitted. Any further actual entry or section shall fail as unexpected content.
## Section rules
Format 1 shall contain exactly one `[AUTO_START]` section.
The section header shall:
- Be spelled exactly `[AUTO_START]`.
- Be the first actual entry after `FORMAT_VERSION=1`.
- Appear exactly once.
- Not contain a value or trailing tokens other than an optional comment.
Unknown sections, duplicate `[AUTO_START]` sections, entries before the section and malformed section headers shall fail clearly.
An immediately terminated or otherwise empty `[AUTO_START]` section is invalid because Registry and Journal are mandatory.
## Process-ID validation
Each active line in `[AUTO_START]` shall be parsed as a `NenjimComponentId` using the existing component-ID rules.
The complete list shall be validated before the first process is started.
Validation shall reject:
- Invalid component-ID syntax.
- Duplicate process IDs.
- Unknown process IDs.
- IDs known only as passive components.
- IDs which the current Hub cannot construct as a canonical `NenjimProcess`.
- A missing Registry entry.
- A missing Journal entry.
- Registry anywhere other than the first position.
- Journal anywhere other than the second position.
Failures shall identify the configuration path, relevant line when applicable, offending value and reason.
No invalid configuration shall fall back to the previous hardcoded startup behaviour.
## Mandatory bootstrap order
Every valid format 1 configuration shall begin with:
```text
nenjim.registry.service
nenjim.journal.service
```
The Registry shall appear exactly once and as the first process.
The Journal shall appear exactly once and as the second process.
The configured order represents process order, while Registry bootstrap necessarily surrounds passive component construction.
The Hub shall perform startup in these phases:
1. Parse and validate the complete configuration.
2. Construct the configured Registry subsystem.
3. Start the Registry process.
4. Register the Registry service as `nenjim.registry.service`.
5. Record the successful Registry startup.
6. Construct and register the complete current passive component graph.
7. Process the remaining `[AUTO_START]` entries in their declared order, beginning with Journal.
8. Announce the existing online point only after every configured process has started successfully.
9. Enter the existing blocking runtime wait.
Journal shall therefore remain the second started process, even though passive component construction occurs between successful Registry startup and Journal construction.
## Passive component construction
After successful Registry startup, the Hub shall eagerly construct and register the current non-process dependency graph required to construct selectable processes.
This includes the existing passive building blocks, adapters and services which do not implement the canonical `NenjimProcess`.
The existing component IDs and dependency wiring shall remain unchanged unless a change is strictly required to separate passive construction from selected process construction.
Passive construction shall not:
- Start background workers.
- Open JavaFX windows.
- Activate a `NenjimProcess`.
- Add an ID to the Hub's started-process snapshot.
- Automatically construct an omitted process.
- Infer process dependencies from constructors or interfaces.
Plain internal dependencies which are not `NenjimComponent` objects may still be constructed by the Hub as part of the passive object graph.
## Lazy process construction
The Hub shall maintain an implementation-only catalogue of the modern process IDs it knows how to construct, or equivalent internal lazy-construction logic.
The catalogue shall describe construction capability without constructing process instances during configuration validation.
No new public process-factory, registration or discovery API shall be introduced.
For each `[AUTO_START]` entry after Registry, the Hub shall:
1. Select the known internal constructor for the exact configured `NenjimComponentId`.
2. Construct the process and any process-specific passive administration view required by its subsystem.
3. Register the constructed process under the configured ID.
4. Resolve the registered object through the canonical `NenjimProcess` contract where applicable.
5. Invoke `start()`.
6. Record the ID only after `start()` returns successfully.
7. Continue to the next configured entry.
A process shall not be constructed speculatively before its entry is reached.
A construction failure shall leave the process unregistered.
A startup failure may leave the already constructed process registered, matching the existing registration-before-start lifecycle. Its ID shall not be added to the started-process snapshot.
## Known selectable processes
The format 1 implementation shall support lazy construction of the modern processes currently known by the active Hub:
```text
nenjim.registry.service
nenjim.journal.service
assetaz.ticker.default
jupiter-perps-alarm.default
evelyn.service.prod
evelyn.service.test
evelyn.iou-burner.prod
nenjim.javafx-runtime.service
evelyn.mission-control.default
nenjim.process-manager.default
```
The version-controlled example shall contain only Registry and Journal. Every optional process, including Jupiter Perps Alarm, shall remain absent until an operator explicitly adds it to the private deployment configuration.
Legacy process prototypes outside the modern Hub component graph shall not become selectable merely because they exist in the repository.
Adding general process discovery is outside this issue.
## Dependency-sensitive examples
The Hub shall preserve configuration order without deriving a dependency graph.
For example, a deployment selecting JavaFX applications must place the JavaFX runtime before those applications.
The Hub does not need a general rule identifying JavaFX applications. Existing JavaFX consumers already reject use of an inactive `JavaFxRuntimeService`.
Likewise, if a selected application currently requires another selected service instance during construction, the configuration must place that service first.
The Hub shall not automatically repair an invalid operational order.
## Default example configuration
Create or update:
```text
conf/NenjimHub.conf.example
```
with a documented, generic format 1 example containing only the mandatory Registry and Journal bootstrap entries:
```text
# Copy this template to conf/NenjimHub.conf before starting Nenjim Hub.
# Registry and Journal are mandatory and must be the first two entries.
# Entries are ordered. List every process dependency manually before its consumers.
FORMAT_VERSION=1
[AUTO_START]
nenjim.registry.service
nenjim.journal.service
```
The example shall explain through comments that:
- The file must be copied to `conf/NenjimHub.conf` before use.
- Registry and Journal are mandatory.
- Entries are ordered.
- Process dependencies must currently be listed manually before their consumers.
The example shall not contain optional deployment-specific process IDs.
The example itself shall not be loaded by the application.
## Headless configuration
Documentation shall include the same minimal headless bootstrap:
```text
FORMAT_VERSION=1
[AUTO_START]
nenjim.registry.service
nenjim.journal.service
```
This configuration shall construct and start only the mandatory Registry and Journal processes. It shall not construct, register or start any optional process.
The JavaFX runtime shall not be initialized merely because JavaFX-capable implementation classes exist in the repository.
## Failure semantics
Configuration and startup remain fail-fast.
Before Registry startup, the Hub shall reject all configuration errors that can be determined from:
- File access.
- Format syntax.
- Format version.
- Section structure.
- Component-ID syntax.
- Duplicate IDs.
- The Hub's known process-construction catalogue.
- Mandatory Registry and Journal placement.
After Registry startup:
- Passive component construction failure stops startup.
- Selected process construction failure stops startup.
- Selected process registration failure stops startup.
- Selected process startup failure stops startup.
- No later configured process is constructed or started.
- The online point is not announced.
This issue shall not introduce general rollback.
Processes which started successfully before a later failure remain represented in the Hub's immutable point-in-time started-process snapshots.
A failing process is never recorded as successfully started.
## Process Manager behaviour
No Process Manager API or polling change is required.
When selected, Nenjim Process Manager continues to poll:
```java
NenjimHub.getStartedProcessIds()
```
It shall therefore display only processes whose startup completed successfully.
Its list shall not be populated from `AUTO_START` directly.
When Process Manager is omitted from `[AUTO_START]`, it is not constructed, registered or started.
## Hub API
No new public operation shall be added to `NenjimHub`.
The existing API remains:
```java
void start() throws Exception;
@NotNull
List<NenjimComponentId> getStartedProcessIds();
```
Configuration parsing, process-construction catalogues and startup planning remain implementation details of the reference Hub.
## Removal of hardcoded startup
Remove the unconditional construction and startup behaviour which currently activates the fixed process set inside `NenjimHubImpl`.
The Hub may retain stable component-ID constants and implementation-only construction methods.
It shall not retain:
- An unconditional hardcoded list equivalent to the old startup sequence.
- A fallback which starts every known process.
- Construction of all known process objects before reading `[AUTO_START]`.
- Construction of a process solely because its implementation is available.
- Special implicit activation of JavaFX applications.
- A second competing autorun mechanism.
The only automatic process-start policy after Registry bootstrap shall be the validated order from `conf/NenjimHub.conf`.
## Documentation
Update the relevant Nenjim documentation and terminology to describe:
- The distinction between passive component construction and selected process construction.
- The mandatory version 1 Hub configuration.
- The exact `[AUTO_START]` grammar.
- Registry and Journal as mandatory first entries.
- Configuration order as the current manual dependency order.
- Omitted processes being neither constructed, registered nor started.
- The example file as a generic copy-only template containing only Registry and Journal.
- The absence of fallback to the example or old hardcoded list.
- Headless operation without JavaFX processes.
- Process Manager as a view of actual successful startup rather than requested autorun.
- Recursive dependency construction as future work, not current behaviour.
Documentation must not describe Context resolution, implementation-version selection, dependency discovery or recursive startup as implemented.
## OpenSpec requirements
Create a new OpenSpec change for issue #81.
Suggested change ID:
```text
81-configure-ordered-process-autorun
```
The OpenSpec artifacts shall specify:
- The mandatory `conf/NenjimHub.conf` path.
- Format version 1.
- The exact `[AUTO_START]` grammar and termination rule.
- Comment and whitespace handling.
- Strict configuration validation.
- Registry and Journal as mandatory first and second entries.
- Eager passive component construction after Registry startup.
- Lazy construction of selected process objects.
- Registration-before-start behaviour.
- Exact ordered startup.
- Omitted-process behaviour.
- Failure and partial-startup semantics.
- The example file's generic, template-only role.
- Removal of the hardcoded startup path.
- The temporary manual process-dependency model.
Introduce a focused Hub configuration capability and update only other canonical specifications whose currently implemented guarantees change.
Keep the OpenSpec change active after implementation until the implementation has been reviewed and accepted. After acceptance, synchronize its delta specifications into the main specifications and archive the change.
## Scope
This issue includes:
- Adding strict format 1 `NenjimHub.conf` parsing.
- Adding the mandatory ordered `[AUTO_START]` section.
- Using `NenjimComponentId` entries.
- Supporting full-line and trailing `#` comments.
- Ending `[AUTO_START]` at the first trimmed empty line or end of file.
- Requiring Registry first and Journal second.
- Validating the complete known process list before Registry startup.
- Starting Registry before passive component construction.
- Constructing and registering all current passive components.
- Lazily constructing, registering and starting selected processes.
- Supporting all modern process IDs currently known by the Hub.
- Preserving configured process order.
- Preserving fail-fast startup and truthful started-process snapshots.
- Adding or updating the generic `conf/NenjimHub.conf.example`.
- Documenting minimal headless configuration.
- Removing unconditional process construction and hardcoded startup.
- Building the complete repository successfully.
## Out of scope
This issue does not implement:
- Automatic dependency discovery.
- Recursive dependency construction.
- Automatic dependency startup.
- Startup-order calculation.
- Reordering or repairing configuration.
- Context definitions.
- Context resolution.
- Artifact-version selection.
- Implementation-version selection.
- Journal-driven process resolution.
- Classloader changes.
- Dynamic process discovery.
- Public process-factory registration.
- Runtime process construction after Hub startup.
- Process stop or restart.
- Startup rollback.
- Health monitoring.
- Recovery or supervision.
- Hub lifecycle events.
- Event subscriptions.
- Configuration reload.
- Runtime configuration editing.
- Command-line configuration-path selection.
- Loading or copying the example configuration.
- General unit tests.
- NenjimTestTool functionality.
- Production deployment automation.
## Acceptance criteria
- [ ] Hub startup reads only `conf/NenjimHub.conf`.
- [ ] A missing, unreadable or non-regular runtime configuration fails startup clearly.
- [ ] `conf/NenjimHub.conf.example` is never used as runtime input.
- [ ] `FORMAT_VERSION=1` is required as the first actual entry.
- [ ] Any format version other than 1 is rejected.
- [ ] Exactly one `[AUTO_START]` section is required.
- [ ] Each active section entry is parsed as a `NenjimComponentId`.
- [ ] Leading and trailing whitespace is handled as specified.
- [ ] Full-line `#` comments are supported.
- [ ] Trailing `#` comments are supported.
- [ ] Comment-only lines inside `[AUTO_START]` do not terminate it.
- [ ] The first trimmed empty line terminates `[AUTO_START]`.
- [ ] End of file may terminate `[AUTO_START]`.
- [ ] Only blank lines and comments are accepted after section termination.
- [ ] Duplicate process IDs are rejected.
- [ ] Unknown process IDs are rejected before process startup.
- [ ] Passive component IDs in `[AUTO_START]` are rejected.
- [ ] Registry is required exactly once as the first process.
- [ ] Journal is required exactly once as the second process.
- [ ] Registry starts before passive component construction.
- [ ] The complete current passive component graph is constructed and registered after Registry startup.
- [ ] Passive component construction starts no `NenjimProcess`.
- [ ] Journal is the second successfully started process.
- [ ] Each remaining process is constructed only when its configured entry is reached.
- [ ] A selected process is registered before its `start()` operation.
- [ ] A successfully started process is recorded after `start()` returns.
- [ ] A failing process is not recorded as successfully started.
- [ ] A process omitted from `[AUTO_START]` is not constructed.
- [ ] A process omitted from `[AUTO_START]` is not registered.
- [ ] A process omitted from `[AUTO_START]` is not started.
- [ ] Configured process order is preserved exactly.
- [ ] Missing process dependencies are not constructed automatically.
- [ ] The Hub does not infer or reorder process dependencies.
- [ ] Startup stops at the first passive-construction, process-construction, registration or process-start failure.
- [ ] No general rollback is introduced.
- [ ] The online point is announced only after every configured process has started successfully.
- [ ] The current modern process IDs, including the optional Jupiter Perps Alarm, are selectable.
- [ ] The example configuration contains only the mandatory Registry and Journal entries.
- [ ] The example configuration contains no optional deployment-specific process IDs.
- [ ] A headless configuration can omit JavaFX runtime, Mission Control and Process Manager.
- [ ] Omitting all JavaFX processes leaves the JavaFX toolkit uninitialized.
- [ ] Process Manager continues to display actual successful startup snapshots rather than configured intent.
- [ ] The former hardcoded process construction and startup path is removed.
- [ ] No fallback starts every known process.
- [ ] No Context, version resolution, recursive dependency startup, events, stop lifecycle or health monitoring is added.
- [ ] No general unit tests or NenjimTestTool functionality are added.
- [ ] Relevant documentation describes only the implemented format 1 behaviour.
- [ ] The repository builds successfully.
- [ ] The OpenSpec change describes only the functionality delivered by this issue.
- [ ] The OpenSpec delta specifications are synchronized and the accepted change is archived.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Background
Issues #77 through #80 established the current Nenjim runtime model:
NenjimHubowns the object graph and process lifecycle.NenjimProcess.NenjimHubImpl.The current Hub always constructs all process objects and then starts this fixed sequence:
This prevents the same build from supporting different deployment roles.
For example, a headless server should be able to omit JavaFX, Mission Control and Process Manager.
Nenjim does not yet have automatic process-dependency resolution. Until that functionality exists, configuration must contain the complete ordered set of processes required by the deployment.
Goal
Introduce the first mandatory
NenjimHub.confformat, identified by format version 1, containing an ordered[AUTO_START]section.The Hub shall:
NenjimProcessobjects explicitly listed in[AUTO_START].A process omitted from
[AUTO_START]shall not be constructed, registered or started.Current transitional model
This issue deliberately implements a transitional runtime model.
All current passive building blocks are constructed eagerly because Nenjim does not yet resolve component dependencies automatically.
Process objects are different:
[AUTO_START].NenjimProcessobject is constructed only when its component ID appears in[AUTO_START].start()operation is invoked.[AUTO_START]does not exist in the runtime object graph or Registry.A service or application role does not by itself determine construction behaviour. The technical distinction is whether the implementation participates in the Hub-managed lifecycle through the canonical
NenjimProcessinterface.The Registry process is the necessary bootstrap exception: it must be constructed and started before other components can be registered.
Future dependency model
The intended future model is top-down recursive dependency construction.
When a process is requested in the future, Nenjim may:
That functionality does not exist yet.
For format 1,
[AUTO_START]is therefore the complete manually ordered process closure required by the deployment. The Hub shall not infer dependencies, insert missing processes, reorder entries, or start processes recursively.If a selected process requires another process object through the current constructor wiring, that dependency must have been selected and constructed earlier in
[AUTO_START].A missing predecessor shall produce a clear fail-fast construction or startup failure. It shall not cause implicit process construction.
Configuration location
The runtime configuration path shall be fixed as:
Mainshall continue to construct and start the reference Hub normally. No command-line configuration-path option is introduced.The Hub shall read only
conf/NenjimHub.conf.The repository shall contain:
The example file exists only as a generic template that an operator can copy and edit.
The application shall never:
conf/NenjimHub.conf.example.The real
conf/NenjimHub.confremains deployment-specific and excluded from Git by the existing ignore rules.A missing, unreadable or non-regular runtime configuration file shall fail Hub startup clearly before any process is started.
Format version
Adding a mandatory runtime configuration is a breaking deployment change. However, because
NenjimHub.confdid not previously exist, this is the first version of this configuration format.The configuration shall therefore require:
Version 1 is the only supported version for this issue.
FORMAT_VERSION=1shall be the first actual configuration entry. Leading blank lines and full-line comments may precede it.Any value other than FORMAT_VERSION=1, as well as missing, malformed or duplicate version declarations, shall fail clearly.
Text format
A minimal generic configuration is:
Each entry in
[AUTO_START]is oneNenjimComponentId.The section order is the requested process construction and startup order.
Operators add their own deployment-specific process IDs and dependencies after copying the example to
conf/NenjimHub.conf.Comments and whitespace
The parser shall support blank lines and
#comments consistently.Outside
[AUTO_START]:#shall be treated as a full-line comment.#after actual content shall begin a trailing comment.Inside
[AUTO_START]:#shall be ignored as a comment and shall not terminate the section.#after a process ID shall begin a trailing comment.[AUTO_START].[AUTO_START].Comment processing shall distinguish comment-only lines from empty terminating lines. A comment-only line inside the section shall not end the section.
There is no quoting or escaping mechanism for
#in format 1 because#is not valid within aNenjimComponentId.After
[AUTO_START]has terminated, only blank lines and comments are permitted. Any further actual entry or section shall fail as unexpected content.Section rules
Format 1 shall contain exactly one
[AUTO_START]section.The section header shall:
[AUTO_START].FORMAT_VERSION=1.Unknown sections, duplicate
[AUTO_START]sections, entries before the section and malformed section headers shall fail clearly.An immediately terminated or otherwise empty
[AUTO_START]section is invalid because Registry and Journal are mandatory.Process-ID validation
Each active line in
[AUTO_START]shall be parsed as aNenjimComponentIdusing the existing component-ID rules.The complete list shall be validated before the first process is started.
Validation shall reject:
NenjimProcess.Failures shall identify the configuration path, relevant line when applicable, offending value and reason.
No invalid configuration shall fall back to the previous hardcoded startup behaviour.
Mandatory bootstrap order
Every valid format 1 configuration shall begin with:
The Registry shall appear exactly once and as the first process.
The Journal shall appear exactly once and as the second process.
The configured order represents process order, while Registry bootstrap necessarily surrounds passive component construction.
The Hub shall perform startup in these phases:
nenjim.registry.service.[AUTO_START]entries in their declared order, beginning with Journal.Journal shall therefore remain the second started process, even though passive component construction occurs between successful Registry startup and Journal construction.
Passive component construction
After successful Registry startup, the Hub shall eagerly construct and register the current non-process dependency graph required to construct selectable processes.
This includes the existing passive building blocks, adapters and services which do not implement the canonical
NenjimProcess.The existing component IDs and dependency wiring shall remain unchanged unless a change is strictly required to separate passive construction from selected process construction.
Passive construction shall not:
NenjimProcess.Plain internal dependencies which are not
NenjimComponentobjects may still be constructed by the Hub as part of the passive object graph.Lazy process construction
The Hub shall maintain an implementation-only catalogue of the modern process IDs it knows how to construct, or equivalent internal lazy-construction logic.
The catalogue shall describe construction capability without constructing process instances during configuration validation.
No new public process-factory, registration or discovery API shall be introduced.
For each
[AUTO_START]entry after Registry, the Hub shall:NenjimComponentId.NenjimProcesscontract where applicable.start().start()returns successfully.A process shall not be constructed speculatively before its entry is reached.
A construction failure shall leave the process unregistered.
A startup failure may leave the already constructed process registered, matching the existing registration-before-start lifecycle. Its ID shall not be added to the started-process snapshot.
Known selectable processes
The format 1 implementation shall support lazy construction of the modern processes currently known by the active Hub:
The version-controlled example shall contain only Registry and Journal. Every optional process, including Jupiter Perps Alarm, shall remain absent until an operator explicitly adds it to the private deployment configuration.
Legacy process prototypes outside the modern Hub component graph shall not become selectable merely because they exist in the repository.
Adding general process discovery is outside this issue.
Dependency-sensitive examples
The Hub shall preserve configuration order without deriving a dependency graph.
For example, a deployment selecting JavaFX applications must place the JavaFX runtime before those applications.
The Hub does not need a general rule identifying JavaFX applications. Existing JavaFX consumers already reject use of an inactive
JavaFxRuntimeService.Likewise, if a selected application currently requires another selected service instance during construction, the configuration must place that service first.
The Hub shall not automatically repair an invalid operational order.
Default example configuration
Create or update:
with a documented, generic format 1 example containing only the mandatory Registry and Journal bootstrap entries:
The example shall explain through comments that:
conf/NenjimHub.confbefore use.The example shall not contain optional deployment-specific process IDs.
The example itself shall not be loaded by the application.
Headless configuration
Documentation shall include the same minimal headless bootstrap:
This configuration shall construct and start only the mandatory Registry and Journal processes. It shall not construct, register or start any optional process.
The JavaFX runtime shall not be initialized merely because JavaFX-capable implementation classes exist in the repository.
Failure semantics
Configuration and startup remain fail-fast.
Before Registry startup, the Hub shall reject all configuration errors that can be determined from:
After Registry startup:
This issue shall not introduce general rollback.
Processes which started successfully before a later failure remain represented in the Hub's immutable point-in-time started-process snapshots.
A failing process is never recorded as successfully started.
Process Manager behaviour
No Process Manager API or polling change is required.
When selected, Nenjim Process Manager continues to poll:
It shall therefore display only processes whose startup completed successfully.
Its list shall not be populated from
AUTO_STARTdirectly.When Process Manager is omitted from
[AUTO_START], it is not constructed, registered or started.Hub API
No new public operation shall be added to
NenjimHub.The existing API remains:
Configuration parsing, process-construction catalogues and startup planning remain implementation details of the reference Hub.
Removal of hardcoded startup
Remove the unconditional construction and startup behaviour which currently activates the fixed process set inside
NenjimHubImpl.The Hub may retain stable component-ID constants and implementation-only construction methods.
It shall not retain:
[AUTO_START].The only automatic process-start policy after Registry bootstrap shall be the validated order from
conf/NenjimHub.conf.Documentation
Update the relevant Nenjim documentation and terminology to describe:
[AUTO_START]grammar.Documentation must not describe Context resolution, implementation-version selection, dependency discovery or recursive startup as implemented.
OpenSpec requirements
Create a new OpenSpec change for issue #81.
Suggested change ID:
The OpenSpec artifacts shall specify:
conf/NenjimHub.confpath.[AUTO_START]grammar and termination rule.Introduce a focused Hub configuration capability and update only other canonical specifications whose currently implemented guarantees change.
Keep the OpenSpec change active after implementation until the implementation has been reviewed and accepted. After acceptance, synchronize its delta specifications into the main specifications and archive the change.
Scope
This issue includes:
NenjimHub.confparsing.[AUTO_START]section.NenjimComponentIdentries.#comments.[AUTO_START]at the first trimmed empty line or end of file.conf/NenjimHub.conf.example.Out of scope
This issue does not implement:
Acceptance criteria
conf/NenjimHub.conf.conf/NenjimHub.conf.exampleis never used as runtime input.FORMAT_VERSION=1is required as the first actual entry.[AUTO_START]section is required.NenjimComponentId.#comments are supported.#comments are supported.[AUTO_START]do not terminate it.[AUTO_START].[AUTO_START].[AUTO_START]are rejected.NenjimProcess.start()operation.start()returns.[AUTO_START]is not constructed.[AUTO_START]is not registered.[AUTO_START]is not started.