## ADDED Requirements ### Requirement: Journal construction preserves process identity and administration boundaries The reference Journal construction boundary SHALL create one Journal object configured with a normalized absolute data root and exposed through both `JournalService` and `NenjimProcess`, plus one distinct `JournalServiceManager` bound to that object through a package-private administration view. The service and process views SHALL preserve object identity. The construction helper SHALL own no lifecycle, SHALL be neither a component nor a process, SHALL not be registered, and SHALL expose neither parser, ingestion, chain state, filesystem administration nor a way to derive the active Journal's manager from an ordinary service reference. #### Scenario: Journal views preserve identity - **WHEN** the Hub obtains a newly constructed Journal assembly - **THEN** its service and process views reference the identical Journal object while its manager is a different object #### Scenario: Ordinary service reference remains read-only - **WHEN** an ordinary consumer receives the public Journal service view - **THEN** the consumer cannot name or derive the package-private administration view or obtain the manager bound to that active Journal ### Requirement: Journal process startup is single-use and publishes atomically The reference Journal service object SHALL implement `NenjimProcess`. Its first `start()` call SHALL be the only accepted attempt, SHALL load only its construction-configured root, and SHALL make query state available only after the complete initial filesystem load succeeds. A later start SHALL fail with `IllegalStateException`, including after a failed first attempt. Queries before successful startup or after failed startup SHALL fail with `IllegalStateException`, and no failed initial load SHALL expose a partial Journal worldview. #### Scenario: Successful initial process start - **WHEN** the configured root and every runtime Journal entry are valid - **THEN** the process returns only after the complete chronological load is queryable #### Scenario: Example-only root starts empty - **WHEN** the configured root exists and contains only valid artifact directories with `.journal.example` files - **THEN** process startup succeeds and the service exposes an empty immutable coordinate set #### Scenario: Query before successful startup - **WHEN** any Journal query is called before startup succeeds or after startup fails - **THEN** it fails with `IllegalStateException` and exposes no candidate state #### Scenario: Failed startup is not retried - **WHEN** the first Journal process start fails and `start()` is called again - **THEN** the second call fails with `IllegalStateException` without another loading attempt #### Scenario: Failed initial load publishes nothing - **WHEN** an earlier runtime entry is valid but any later entry fails root, layout, parsing, placement or chain validation - **THEN** the original meaningful failure propagates and no accepted candidate revision becomes queryable ### Requirement: Passive Journal service manager `JournalServiceManager` SHALL expose exactly the normalized configured `journalRoot()` and explicit `refresh()` administration operations. It SHALL be neither a Nenjim component nor a Nenjim process, SHALL be retained privately by the Hub, SHALL bind to exactly one Journal object through non-public administration, and SHALL expose no start, stop, service accessor, query, parser, ingestion or chain-state operation. Refresh before successful Journal process startup SHALL fail with `IllegalStateException`. #### Scenario: Manager contract is passive - **WHEN** the public manager interface and reference manager are inspected - **THEN** only root reporting and refresh are available and the manager has no lifecycle or component identity #### Scenario: Refresh follows process startup - **WHEN** refresh is requested before its Journal process has started successfully - **THEN** the manager rejects it with `IllegalStateException` #### Scenario: Manager delegates after startup - **WHEN** refresh is requested after successful Journal startup - **THEN** the manager delegates through the non-public admin view to the same active Journal object ## MODIFIED Requirements ### Requirement: Filesystem-independent read-only Journal service `JournalService` SHALL extend `NenjimComponent` as the ordinary registrable, application-facing, filesystem-independent, read-only API. It SHALL list known artifact coordinates and chronological revisions; obtain latest, exact, and newest-at-or-before revisions; obtain an exact artifact release from a selected revision; return immutable results without `null`; and expose no lifecycle, path, refresh, parser, configuration, administration or mutation operation. Its queries SHALL be available only after the Journal process has completed successful startup. #### Scenario: Chronological and latest queries - **WHEN** an artifact has several accepted revisions after successful startup - **THEN** the service lists all complete snapshots in ascending Journal-version order and returns the chain head as latest #### Scenario: Exact and as-of historical queries - **WHEN** a caller requests an exact revision or the newest revision at or before a Journal version - **THEN** the service returns the complete worldview from that chain position rather than filtering a newer snapshot by release publication time #### Scenario: Release query from selected worldview - **WHEN** a caller requests an exact artifact version from a selected revision - **THEN** the release, including license, content, dependencies, and policy context in that snapshot, is returned only if that revision knows it #### Scenario: Missing query result - **WHEN** a coordinate, revision, as-of revision, or artifact release is unknown after successful startup - **THEN** the service returns an empty optional or immutable empty collection rather than `null` #### Scenario: Read-only component boundary - **WHEN** an ordinary consumer receives `JournalService` - **THEN** the interface is registrable as a component but provides no start, stop, filesystem root, refresh, parsing, update, ingestion, administration or other mutation operation ### Requirement: Filesystem-backed lifecycle loading The reference Journal service process SHALL own a configured existing readable root and SHALL use non-public filesystem loading to discover runtime files only at `//.journal`, ignore `.journal.example`, validate directory and filename placement against parsed content, sort each artifact's files chronologically, read complete UTF-8 text, and supply it to the existing internal ingestion operation. Initial loading SHALL publish only after the complete root succeeds. Later refresh SHALL target the active service through its non-public administration view. Neither path SHALL create, overwrite, delete, publish, download, synchronize or watch files. #### Scenario: Valid filesystem load - **WHEN** an artifact directory contains chronologically named valid genesis and successor `.journal` files whose content identity matches their placement - **THEN** initial process startup or a later explicit refresh ingests both complete UTF-8 texts in chronological order and exposes their chain through the service #### Scenario: Example files are ignored - **WHEN** a directory contains `.journal.example` - **THEN** loading does not ingest it as a runtime Journal #### Scenario: Invalid directory placement - **WHEN** a runtime Journal's metadata-derived coordinate differs from its parent directory name - **THEN** loading fails clearly #### Scenario: Invalid filename placement - **WHEN** a runtime filename does not use the strict timestamp syntax or differs from the parsed `JOURNAL_VERSION` - **THEN** loading fails clearly #### Scenario: Invalid root - **WHEN** the configured Journal root is missing, not a directory, or unreadable - **THEN** startup or refresh fails clearly without creating it #### Scenario: Unexpected filesystem entry - **WHEN** the configured root contains a runtime entry outside the artifact-directory/revision-file structure - **THEN** loading fails rather than silently treating it as a Journal ### Requirement: Explicit idempotent refresh The passive service manager SHALL support explicit refresh only after successful Journal process startup. Repeating refresh for unchanged files SHALL be idempotent, and a later refresh SHALL discover valid newly added successors while preserving existing historical revisions and the existing per-ingestion atomicity. #### Scenario: Unchanged refresh - **WHEN** refresh runs twice after startup without filesystem changes - **THEN** the second run leaves all chains unchanged and succeeds through ingestion idempotency #### Scenario: New revision discovered - **WHEN** a valid successor file is added after successful startup or an earlier refresh - **THEN** the next refresh ingests it and the read-only service exposes it as the new head #### Scenario: Refresh is not a service operation - **WHEN** ordinary consumers inspect `JournalService` and `NenjimProcess` - **THEN** neither interface exposes refresh ## REMOVED Requirements ### Requirement: Journal service lifecycle manager **Reason**: Lifecycle ownership belongs to the Journal service object as a Hub-managed `NenjimProcess`; the manager is only a passive administrative capability. **Migration**: The Hub starts the Journal through its process view and retains a distinct manager exposing only `journalRoot()` and `refresh()`.