78: Make JournalService a Hub-managed Nenjim process and integrate it into startup

This commit is contained in:
2026-09-02 16:46:51 +02:00
parent f5fc5bb3b5
commit 7b1f6d18eb
19 changed files with 858 additions and 254 deletions
+31 -20
View File
@@ -20,8 +20,9 @@
<main>
<h1>Nenjim</h1>
<p class="status"><strong>Implementation status:</strong> Journal format version 1, the immutable Java model,
internal strict parser, read-only <code>JournalService</code>, explicitly refreshed lifecycle
<code>JournalServiceManager</code>, and the first central component Registry are implemented. Contexts,
internal strict parser, read-only <code>JournalService</code> with a Hub-managed process implementation,
passive explicitly refreshed <code>JournalServiceManager</code>, and the first central component Registry
are implemented. Contexts,
resolution, classloading, discovery, runtime loading/removal, downloading, publishing, synchronization,
watching, signatures, permissions, and license filtering remain future work.</p>
@@ -96,20 +97,26 @@ PREFERRED=nenjim:com_r35157_nenjim-hubd-api=1.0.3:'Built together'</code></pre>
semantically inconsistent content fails with source name, one-based line number, and a reason. Validation is
complete before service state changes. Returned objects and collections are immutable and defensively copied.</p>
<h2>Service, ServiceManager, packages, and disk layout</h2>
<h2>Service, process, ServiceManager, packages, and disk layout</h2>
<p>A <code>Service</code> is the public domain API used by applications and other services during ordinary
operation. <code>JournalService</code> is therefore filesystem-independent and read-only: it exposes current
and historical Journal queries without lifecycle, paths, refresh, parser, or mutation operations.</p>
<p>A <code>ServiceManager</code> is the lifecycle and administrative API owned by a composition/lifecycle owner.
<code>JournalServiceManager</code> starts and stops the Journal service, reports its normalized data root,
performs explicit refresh, and exposes <code>JournalService</code> only after complete successful initial
loading. Its reference implementation reads UTF-8 runtime files chronologically and validates directory and
filename placement. It creates, overwrites, and deletes nothing.</p>
<p><code>JournalServiceImpl</code> keeps exact-text SHA-256 identity, chain state, idempotency, conflicts, forks,
and atomic ingestion internal. The public package contains only the two central interfaces; composed models,
value types, and exceptions live under <code>.model</code>, <code>.valuetypes</code>, and
<code>.exception</code>, while parser, ingestion, chain state, and filesystem loading live under
<code>.impl.ref</code> without leaking through public signatures.</p>
operation. <code>JournalService</code> is a registrable component but remains filesystem-independent and
read-only: it exposes current and historical Journal queries without lifecycle, paths, refresh, parser, or
mutation operations. Queries become available only after successful Journal process startup.</p>
<p>The Hub constructs one Journal object exposed as both <code>JournalService</code> and
<code>NenjimProcess</code>, plus one distinct passive <code>JournalServiceManager</code>. The manager reports
the normalized data root and performs explicit refresh; it has no start, stop, service accessor, component
identity, or process lifecycle. It delegates through a package-private administration view that ordinary
service consumers cannot name or derive.</p>
<p>The Journal process reads UTF-8 runtime files chronologically and validates directory and filename placement.
Its complete initial worldview is published only after every runtime file succeeds; failed startup leaves
queries unavailable and cannot be retried on the same instance. Later refresh remains explicit, idempotent,
and atomic per ingestion. Neither startup nor refresh creates, overwrites, or deletes Journal files.</p>
<p>The package-private <code>JournalServiceImpl</code> keeps exact-text SHA-256 identity, chain state,
idempotency, conflicts, forks, and ingestion internal. The public package contains only the two central
interfaces; composed models, value types, and exceptions live under <code>.model</code>,
<code>.valuetypes</code>, and <code>.exception</code>, while parser, ingestion, chain state, filesystem
loading, and the admin boundary live under <code>.impl.ref</code> without leaking through public
signatures.</p>
<pre><code>data/nenjim/journals/
└── &lt;artifact-coordinate&gt;/
├── &lt;journal-version&gt;.journal
@@ -135,11 +142,15 @@ PREFERRED=nenjim:com_r35157_nenjim-hubd-api=1.0.3:'Built together'</code></pre>
registered, and cannot start anything. The internal administration interface must remain package-private so
an ordinary service consumer cannot cast the Registry object to a mutation view.</p>
<p><code>NenjimHubImpl</code> is the global composition and runtime owner. It constructs the Registry assembly,
starts and registers the Registry first, records its successful process ID, and then constructs and registers
the hardcoded component graph in dependency order. The Ticker explicitly selects the Raydium EVE/USDT source
ID while the hardcoded source remains registered but inactive. The Hub activates only the existing explicit
five-process sequence after the Registry; it does not start every registered process. Successful process IDs
are exposed as immutable ordered point-in-time snapshots, without implying continued health.</p>
starts and registers Registry first, and records its successful process ID. It then constructs the Journal
assembly for <code>data/nenjim/journals</code>, registers <code>nenjim.journal.service</code>, starts Journal
second, and records it only after complete successful loading. Only then does the Hub construct the hardcoded
business component graph in dependency order. A Journal failure therefore stops startup before Ticker,
Evelyn, Burner, Mission Control, the online point, and the blocking wait.</p>
<p>The Ticker explicitly selects the Raydium EVE/USDT source ID while the hardcoded source remains registered but
inactive. After Registry and Journal, the Hub activates only the existing explicit five-business-process
sequence; it does not start every registered process. Successful process IDs are exposed as immutable ordered
point-in-time snapshots, without implying continued health.</p>
<p><code>com.r35157.nenjim.hubd.Main</code> remains only the outer Java bootstrap. It constructs the reference Hub
through the public <code>NenjimHub</code> interface and calls <code>start()</code> once. The Hub is neither a
component nor a process and is not registered inside its own Registry.</p>