94: Buy back Evelyn IOU tokens only below the Evelyn reference price

This commit is contained in:
2026-10-07 08:21:52 +02:00
parent 00a7f13c6f
commit e283f0b8f2
22 changed files with 649 additions and 17 deletions
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-10-06
@@ -0,0 +1,29 @@
# Design
## Context
See proposal.md for motivation and the two delta specifications for required behavior. The burner already selects one rounded, reserve/minimum/maximum-qualified input, invokes Jupiter at most once, and then independently reloads EVE for burn evaluation. Its fresh canonical EVE/USDT reader is also used for burn valuation. The Hub constructs processes in the manually configured order and rejects unavailable process dependencies.
## Goals / Non-Goals
**Goals:** Insert the purchase condition at the last point before a new Jupiter attempt, use the corresponding live reference API, and retain independent burn and pending-transaction behavior.
**Non-Goals:** A general price-policy framework, another clock/configuration/freshness option, duplicated curve calculations, stored-history decisions, or changes to transaction execution, Ticker sources, lifecycle and deployment selection.
## Decisions
1. Add a required `EvelynStatusService` constructor dependency beside Ticker. Production composition uses the existing `requireProcessDependency` guard for `evelyn.status.prod`. The Hub does not infer or start dependencies; operators must place Ticker and Production status before the burner. Constructing a private reference calculator in the burner would duplicate ownership and risk policy drift.
2. After the first eligible rounded input is selected, reuse `findFreshPrice(eveUsdtTradingPair)`, obtain the reference through `getReferencePrice(Instant.now())`, validate its canonical pair and positive amount, and compare with `BigDecimal.compareTo`. This avoids division/index rounding and keeps the check close to submission. Checking before input selection would age the decision during balance/mint work; history/chart reads would use stale sample time.
3. A rejected condition returns only from `attemptAtMostOneSwap`, preserving the unconditional later `processCompleteEveBalance`. No other input can bypass a globally rejected EVE price. Missing/invalid reference or runtime lookup failure produces a safe warning; an at/above comparison logs the values and decision instant. No suspension state is set. Burn valuation independently reads its existing fresh price and never depends on reference availability.
4. Pending burn and swap paths stay ahead of input selection. Reconciliation is read-only regardless of price, and only a newly eligible purchase after reconciliation invokes the gate. Amount limits, precision, unknown-outcome handling and notifications remain as existing contracts define.
## Risks / Trade-offs
- [Market movement after observation] → Use the existing maximum price age and the last purchase-selection point; Jupiter execution and slippage rules remain unchanged.
- [Reference service failure] → Skip the purchase for this iteration, keep burn processing and re-evaluate next time; log exception type without arbitrary provider text.
- [Missing deployment predecessor] → Fail clearly through existing Hub dependency validation; document order without editing private deployment configuration.
- [Unknown transaction after restart] → Retain current pending-state/restart contracts; the price gate cannot replace reconciliation.
## Migration Plan
Compile and verify offline, then review the change. A later separately authorized deployment must have `assetaz.ticker.default` and `evelyn.status.prod` before a selected `evelyn.iou-burner.prod`. This implementation request changes no live configuration, performs no transactions and deploys nothing. Rollback restores the preceding application version and its constructor composition; uncertain transactions must first be reconciled under the existing restart rules.
@@ -0,0 +1,28 @@
# Proposal
## Why
Issue #94 requires Evelyn IOU buybacks to reduce supply specifically while the Evelyn Price Index is below zero. The burner currently buys whenever an input is eligible, so it needs the existing reference-price policy before submitting a new purchase while preserving independent EVE burning.
## What Changes
- Permit new buybacks only with a fresh canonical EVE/USDT price strictly below the corresponding Evelyn status service's reference price at the current decision instant.
- Skip only the purchase when either price is unusable or the market price is at/above reference; continue existing EVE burn processing and re-evaluate next iteration.
- Preserve pending-burn priority, read-only pending-swap reconciliation, at most one new swap, and all existing amount, reserve, precision and transaction rules.
- Inject the Production Evelyn status service through the existing Hub composition, documenting its explicit startup dependency and the purchase-only policy.
- Update constructor/domain JavaDoc and operating documentation and verify the boundaries and recovery paths offline.
## Capabilities
### New Capabilities
None.
### Modified Capabilities
- `evelyn-iou-burner-service`: Gate new purchases on the existing reference-price API while keeping reconciliation and burns independent.
- `nenjim-hub-configuration`: Supply the corresponding Production status service to the burner using existing explicit dependency ordering.
## Impact
The burner constructor gains an `EvelynStatusService` dependency, supplied by `NenjimHubImpl`. Runtime input configuration, schedule, Ticker sources, history, ValueTags and live deployment configuration remain outside this change. Verification uses controlled offline collaborators without financial transactions or permanent test additions.
@@ -0,0 +1,71 @@
# Spec Delta
## MODIFIED Requirements
### Requirement: At most one confirmed swap attempt per iteration
After selecting a positive exact amount and satisfying the current below-reference price condition, the service SHALL invoke the existing Jupiter exact-input operation once with the selected CIS-resolved input mint, fixed EVE output mint, selected amount, and configured slippage. Normal return SHALL be treated as already `CONFIRMED` and SHALL NOT trigger a second confirmation wait. Once invoked, no later input currency SHALL be attempted in that iteration regardless of success or failure, and the service SHALL proceed to reload the complete EVE balance whenever processing was not interrupted.
A structured definitive on-chain swap failure SHALL be logged without suspending later-process swaps. A timed-out outcome or known-signature confirmation communication error SHALL retain process-local pending swap signature, canonical input, attempted amount and original validity metadata for later read-only reconciliation. Proven pre-submission errors SHALL permit a fresh attempt in a later scheduled iteration. An ambiguous post-submission error without a trustworthy signature SHALL retain manual suspension. Interruption SHALL preserve available pending context and propagate normally. No unknown outcome SHALL cause automatic rebuilding, re-signing or resubmission; pending swaps SHALL still permit existing EVE burn evaluation.
#### Scenario: First swap fails definitively
- **WHEN** the first attempted input returns a definitive on-chain failure
- **THEN** no second input is attempted in that iteration, the EVE balance is still reloaded, and a later iteration may attempt a new swap
#### Scenario: Swap outcome is unknown
- **WHEN** the attempted swap times out, throws an I/O failure that permits unknown post-submission status, or is interrupted
- **THEN** no equivalent or alternative swap is attempted while its outcome is unresolved; a known signature is checked in later iterations and a signature-less ambiguous submission requires manual reconciliation
#### Scenario: Swap returns normally
- **WHEN** Jupiter returns a successful result whose transaction already reached `CONFIRMED`
- **THEN** the burner performs no additional confirmation wait and reloads the wallet instead of deriving its burn amount only from the returned output amount
### Requirement: Production burner accepts USDT and SyrupUSDC
The production Hub SHALL configure USDT first with reserve 0.1, minimum input 0.05 and maximum input 0.25 USDT, and SyrupUSDC second with reserve 0.095, minimum input 0.045 and maximum input 0.2 SyrupUSDC. These SHALL be token-denominated limits without a USD-value guarantee. The production EVE burn minimum SHALL be 0.1 EVE and its retained reserve SHALL be 0.01 EVE, as selected by the owner on 2026-10-06, configured as MoneyAmount values using the canonical EVE UUID. The production Hub SHALL supply its corresponding Production Evelyn status service for current reference-price decisions. The existing burner wallet, Jupiter route selection, registration, hourly interval, slippage, EVE/USDT freshness, confirmation settings and burn recovery behavior SHALL be preserved without new Ticker sources or history storage.
#### Scenario: Production inputs and settings
- **WHEN** the Hub constructs the production burner
- **THEN** it supplies the exact reserves, minima and maxima as MoneyAmount values in USDT-then-SyrupUSDC priority, supplies minimum burn 0.1 EVE/reserve 0.01 EVE and the Production status service, and retains the other existing production arguments
#### Scenario: Production burn threshold
- **WHEN** production EVE balance is below 0.11, exactly 0.11, or 0.135 with usable mint precision and fresh price
- **THEN** below 0.11 produces no burn, 0.11 burns 0.1 and 0.135 burns 0.125; successful burns retain 0.01 EVE
## ADDED Requirements
### Requirement: New buybacks require a below-reference market price
An otherwise eligible new buyback SHALL require a fresh canonical EVE/USDT observation within the existing maximum price age and a usable canonical EVE/USDT reference price from the injected corresponding Evelyn status service at the current decision instant. Both prices SHALL be positive. Only actual price strictly below reference SHALL permit submission; equality SHALL not qualify. The existing public reference operation SHALL be reused without copying curve calculations or reading stored history.
#### Scenario: Strict boundary below reference
- **WHEN** an input is otherwise eligible and reference price is 15 USDT/EVE
- **THEN** market price 14.99 permits the existing buyback, while 15.00 and 15.01 submit no new swap from any input in that iteration
#### Scenario: Required prices are unusable
- **WHEN** market observation is missing, stale, incomplete, unavailable or has an invalid pair/non-positive price, or reference lookup throws, is missing or has an invalid pair/non-positive price
- **THEN** no new swap is submitted and a safe diagnostic explains why the purchase was skipped
#### Scenario: Reference uses the current decision instant
- **WHEN** the first usable input is ready for a new swap
- **THEN** the corresponding status service is asked for its reference price at the current instant rather than using a sampled history point or the observation timestamp
### Requirement: Price skips preserve independent burn processing and recovery
A rejected buyback price condition SHALL skip purchases only, continue complete EVE-balance processing under the existing independent burn requirements, and SHALL NOT create a suspension. Each subsequent otherwise eligible iteration SHALL re-evaluate prices. Pending-burn priority and read-only pending-swap reconciliation SHALL remain independent of the new-purchase condition; any newly permitted purchase after reconciliation SHALL pass the current price check.
#### Scenario: Existing EVE burns at or above reference
- **WHEN** market price is equal to or above reference and existing EVE satisfies its own reserve, minimum, precision, fresh valuation and transaction requirements
- **THEN** no new swap occurs and the existing eligible EVE is burned normally
#### Scenario: Reference unavailable but burn valuation is usable
- **WHEN** reference lookup is unavailable or invalid but existing EVE and its fresh canonical valuation satisfy the burn requirements
- **THEN** the purchase is skipped and the independent eligible burn still occurs
#### Scenario: Next scheduled iteration recovers
- **WHEN** one iteration skips a purchase because its prices do not qualify and a later otherwise eligible iteration has usable prices below reference
- **THEN** the later iteration can attempt its one new swap without a restart or manual reset
#### Scenario: Pending swap is resolved above reference
- **WHEN** a pending swap resolves read-only at or above reference
- **THEN** it is cleared normally, any otherwise eligible new purchase is price-checked and skipped, and existing EVE burn evaluation continues
#### Scenario: Unresolved swap and pending burn retain priority
- **WHEN** a swap remains unresolved or the iteration starts with a pending burn
- **THEN** existing transaction-priority rules apply without evaluating a new-purchase price condition or submitting a new swap
@@ -0,0 +1,48 @@
# Spec Delta
## MODIFIED Requirements
### Requirement: Selected processes are constructed and started lazily in exact order
The Hub SHALL support the modern process IDs `nenjim.registry.service`, `nenjim.journal.service`, `assetaz.ticker.default`, `jupiter-perps-alarm.default`, `evelyn.status.prod`, `evelyn.status.test`, `evelyn.iou-burner.prod`, `evelyn.liquidity.prod`, `nenjim.javafx-runtime.service`, `evelyn.mission-control.default`, and `nenjim.process-manager.default` through implementation-only construction capability that creates no process instance during validation. After passive composition, the Hub SHALL visit every configured entry after Registry in declared order, beginning with Journal. At each entry it SHALL construct only that process and any explicitly composed process-specific passive dependencies or administration view, register the process under the exact configured ID, resolve it through the canonical `NenjimProcess` contract where applicable, call `start()`, and record the ID only after successful return.
The production IOU burner SHALL receive the already constructed Production Evelyn status service, and SHALL require both Ticker and `evelyn.status.prod` to precede `evelyn.iou-burner.prod`. The configuration SHALL be the complete manually ordered process dependency closure. The Hub SHALL not discover, insert, recursively construct, reorder, or automatically start dependencies. A process omitted from `[AUTO_START]` SHALL not be constructed, registered, started, or recorded, even when its implementation is available. Legacy process prototypes outside the modern Hub graph SHALL not be selectable.
#### Scenario: Configured process starts successfully
- **WHEN** a configured process entry is reached and its dependencies are already available
- **THEN** that process is constructed, registered, started, and recorded before the next entry is reached
#### Scenario: Process is omitted
- **WHEN** a known process ID does not appear in `[AUTO_START]`
- **THEN** no instance of that process is constructed or registered and its lifecycle is never started or recorded
#### Scenario: Jupiter Perps Alarm is selected
- **WHEN** `jupiter-perps-alarm.default` is explicitly listed after its required predecessors
- **THEN** the otherwise inactive modern alarm process is constructed, registered, started and recorded at that exact position
#### Scenario: Dependency order is invalid
- **WHEN** a selected process is reached before a process dependency required by its current constructor or startup behavior
- **THEN** construction or startup fails clearly without implicit dependency construction, repair, or reordering
#### Scenario: JavaFX processes are omitted
- **WHEN** a valid headless plan omits `nenjim.javafx-runtime.service`, `evelyn.mission-control.default`, and `nenjim.process-manager.default`
- **THEN** none of those objects is constructed or registered and the JavaFX toolkit remains uninitialized by the Hub
#### Scenario: Renamed status services retain dependency wiring
- **WHEN** `evelyn.status.prod` and `evelyn.status.test` are listed after Ticker and before Mission Control
- **THEN** the Hub constructs separate Production/Test status services, registers the renamed IDs, and injects the corresponding typed service views into Mission Control in the configured order
#### Scenario: Deployment still contains an old status ID
- **WHEN** a private deployment configuration contains `evelyn.service.prod` or `evelyn.service.test`
- **THEN** validation rejects the unknown ID before startup; deployment migration replaces only that ID with `evelyn.status.prod` or `evelyn.status.test`, preserving selection and order
#### Scenario: Liquidity is explicitly selected
- **WHEN** `evelyn.liquidity.prod` is reached in a valid startup plan
- **THEN** the Hub loads its runtime configuration, binds the dedicated signer/wallet and Jupiter service to each other, constructs direct Raydium access and registers/starts the liquidity process without inserting a Ticker or status dependency or reordering the plan
#### Scenario: Production burner has its reference-price dependency
- **WHEN** `evelyn.iou-burner.prod` is reached after Ticker and `evelyn.status.prod`
- **THEN** the Hub injects the corresponding Production status service for buyback price decisions
#### Scenario: Production burner precedes its status dependency
- **WHEN** the burner is reached without a previously constructed Production status service
- **THEN** construction fails clearly without creating or starting the omitted dependency or the burner
@@ -0,0 +1,15 @@
# Tasks
## 1. Purchase policy and independent burns
- [x] 1.1 Require the corresponding Evelyn status service and gate a fully eligible new purchase on fresh canonical actual price strictly below its current reference; verify constructor validation, below/equal/above and unavailable/invalid prices with controlled offline checks.
- [x] 1.2 Update constructor/domain JavaDoc and Evelyn operating documentation; verify price skips still burn eligible existing EVE, re-evaluate next iteration and preserve pending burn/swap priority in the same offline checks.
## 2. Hub composition
- [x] 2.1 Inject the Production status dependency through the existing Hub guard and document the explicit Ticker/status/burner order; verify production arguments and fail-fast dependency behavior without starting the Hub or editing deployment configuration.
## 3. Integrated verification
- [x] 3.1 Compile main and existing test sources through normal Gradle/Detag, execute focused offline purchase/burn/recovery checks and relevant prior burner harnesses, and record their final results without adding permanent tests or running live transactions.
- [x] 3.2 Validate the scoped OpenSpec change strictly and check whitespace and changed-file scope; deliver completed planning artifacts and verification evidence for review.
@@ -0,0 +1,40 @@
# Verification
Verified on 2026-10-06 with `/usr/local/software/java/jfx-25`.
## Compilation and controlled acceptance checks
- `JAVA_HOME=/usr/local/software/java/jfx-25 ./gradlew compileJava compileTestJava --offline --no-daemon` → **BUILD SUCCESSFUL in 8s**. Normal Gradle-integrated Detag and both source compilations executed. The initial sandbox attempt could not create the existing Gradle cache lock outside the workspace; the same compilation passed with approved cache access.
- Temporary sources in `/tmp/evelyn-issue94` compiled with `javac --enable-preview --release 25 -cp 'build/classes/java/main:build/libs/*' -d /tmp/evelyn-issue94`.
- `java --enable-preview -cp '/tmp/evelyn-issue94:build/classes/java/main:build/libs/*' Issue94Verification` → **PASS: 459 focused issue #94 assertions**.
- The copied `Issue93Verification` → **PASS: 246 burn-policy regression assertions**.
- The copied `Issue92Verification` → **PASS: 115 input-minimum regression assertions**.
- The copied `Issue91Verification`, restricted to burner checks → **PASS: 80 pending-swap/recovery regression assertions**. Unchanged Solana/Jupiter library checks were not rerun.
- Production composition source check verifies the corresponding Production status dependency and preserved input reserves/minima/maxima, EVE burn minimum/reserve, hourly interval, slippage, freshness and finalization arguments.
- An INFO/WARN-enabled controlled run verifies purchase-skip reasons for at/above reference, unavailable/invalid reference and unusable market price, without arbitrary reference/Ticker exception messages.
The **900** controlled assertions invoke the actual burner iteration with offline wallet, chain, swap, Ticker, reference and notification collaborators. No RPC, signing, live financial operation, application/Hub startup or deployment configuration read occurs. The Hub dependency guard is invoked directly without constructing a Hub. No permanent automated tests were added. Prior harness copies only add an always-below reference stub to constructor calls and update #92's expected canonical EVE/USDT lookup count for eligible purchases; original temporary files remain intact.
The #94 harness covers 14.99/15.00/15.01 against reference 15, numeric equality across scales, a close below-reference decimal, the current reference decision instant instead of observation/history time, complete independent burns and reserve preservation, missing/unavailable/non-positive/null-amount/wrong-pair market and reference data, stale market observations, fresh independent burn valuation after a purchase-price failure, stale burn valuation postponement, next-iteration recovery from every rejection category, input priority and amount limits, below-minimum input fallback, no-eligible-input/direct-EVE-only paths, manual swap suspension and null status validation. It verifies original-signature read-only reconciliation while price is above reference, unresolved retention, definitive success/failure/proven expiry followed by a newly rejected purchase, later below-reference recovery, and simultaneous pending burn/swap priority with no reference lookup or new transaction. PriceObservation itself rejects null observation timestamp/price before they can reach the burner.
An initial temporary harness compilation used the wrong fully qualified component-ID type; it was corrected to the repository's existing `com.r35157.nenjim.service.registry.valuetypes.NenjimComponentId`. Final compiled checks pass. Concurrent initial Java invocations reported harmless performance-data lock warnings; the controlled diagnostic run disabled performance data. No production fix was needed for either verification-only issue.
## Review and workflow
Parent independent review of the proposal/specs/design, implementation, operating documentation and controlled harness found no actionable findings. The existing malformed burn JavaDoc line was corrected while updating that same list item. Scope is limited to the required reference dependency, new-purchase condition, Hub composition, related documentation and two OpenSpec capability deltas. Transaction execution, reconciliation, burn valuation/policy, ValueTags, scheduling and private deployment files retain their existing behavior.
Strict validation of the active change and `git diff --check` pass. All four planning artifact types and all five implementation tasks are complete. The active change is ready for review; main specifications have not been synchronized and the change has not been archived.
No deployment, commit, push, Gitea write or live integration was performed.
## Follow-up: clearer purchase-skip logs
The owner's requested logging refinement keeps price eligibility unchanged. INFO price skips now show a direct labelled comparison, for example `Skipping buyback as EVE price is at or above reference (market=15.01 >= reference=15 USDT/EVE)`, followed by the trading pair, decision instant and next action. Prices use plain decimals without redundant trailing zeros. WARN skips retain their reason; unavailable or invalid reference-price diagnostics also include the known market price.
`JAVA_HOME=/usr/local/software/java/jfx-25 ./gradlew compileJava --offline --no-daemon` passed. The existing temporary #94 harness passed its 459 assertions again with INFO/WARN enabled. Its captured output in `/tmp/evelyn-issue94/issue94-logging-refinement.log` confirms the numeric comparison for both equality and higher prices, reference failure details, missing/stale market diagnostics and exclusion of arbitrary exception messages. No new tests were added.
## Finalization
On 2026-10-06, the owner requested synchronization and archiving. Both capability deltas were merged into the main specifications for `evelyn-iou-burner-service` and `nenjim-hub-configuration`, preserving unrelated requirements and existing purpose sections. Every delta requirement was compared against the resulting main spec, and strict validation of both main specs and the completed change passed; only informational hints about long requirement descriptions were reported.
The seven completed change files, including `.openspec.yaml` and all five completed tasks, were archived intact to `openspec/changes/archive/2026-10-06-94-gate-buybacks-on-evelyn-reference-price`. OpenSpec reports no remaining active changes. This finalization records the subsequent sync/archive after the initial implementation and logging-refinement verification above.
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-10-06
@@ -0,0 +1,29 @@
# Design
## Context
See proposal.md for motivation and the two delta specifications for required behavior. The burner already selects one rounded, reserve/minimum/maximum-qualified input, invokes Jupiter at most once, and then independently reloads EVE for burn evaluation. Its fresh canonical EVE/USDT reader is also used for burn valuation. The Hub constructs processes in the manually configured order and rejects unavailable process dependencies.
## Goals / Non-Goals
**Goals:** Insert the purchase condition at the last point before a new Jupiter attempt, use the corresponding live reference API, and retain independent burn and pending-transaction behavior.
**Non-Goals:** A general price-policy framework, another clock/configuration/freshness option, duplicated curve calculations, stored-history decisions, or changes to transaction execution, Ticker sources, lifecycle and deployment selection.
## Decisions
1. Add a required `EvelynStatusService` constructor dependency beside Ticker. Production composition uses the existing `requireProcessDependency` guard for `evelyn.status.prod`. The Hub does not infer or start dependencies; operators must place Ticker and Production status before the burner. Constructing a private reference calculator in the burner would duplicate ownership and risk policy drift.
2. After the first eligible rounded input is selected, reuse `findFreshPrice(eveUsdtTradingPair)`, obtain the reference through `getReferencePrice(Instant.now())`, validate its canonical pair and positive amount, and compare with `BigDecimal.compareTo`. This avoids division/index rounding and keeps the check close to submission. Checking before input selection would age the decision during balance/mint work; history/chart reads would use stale sample time.
3. A rejected condition returns only from `attemptAtMostOneSwap`, preserving the unconditional later `processCompleteEveBalance`. No other input can bypass a globally rejected EVE price. Missing/invalid reference or runtime lookup failure produces a safe warning; an at/above comparison logs the values and decision instant. No suspension state is set. Burn valuation independently reads its existing fresh price and never depends on reference availability.
4. Pending burn and swap paths stay ahead of input selection. Reconciliation is read-only regardless of price, and only a newly eligible purchase after reconciliation invokes the gate. Amount limits, precision, unknown-outcome handling and notifications remain as existing contracts define.
## Risks / Trade-offs
- [Market movement after observation] → Use the existing maximum price age and the last purchase-selection point; Jupiter execution and slippage rules remain unchanged.
- [Reference service failure] → Skip the purchase for this iteration, keep burn processing and re-evaluate next time; log exception type without arbitrary provider text.
- [Missing deployment predecessor] → Fail clearly through existing Hub dependency validation; document order without editing private deployment configuration.
- [Unknown transaction after restart] → Retain current pending-state/restart contracts; the price gate cannot replace reconciliation.
## Migration Plan
Compile and verify offline, then review the change. A later separately authorized deployment must have `assetaz.ticker.default` and `evelyn.status.prod` before a selected `evelyn.iou-burner.prod`. This implementation request changes no live configuration, performs no transactions and deploys nothing. Rollback restores the preceding application version and its constructor composition; uncertain transactions must first be reconciled under the existing restart rules.
@@ -0,0 +1,28 @@
# Proposal
## Why
Issue #94 requires Evelyn IOU buybacks to reduce supply specifically while the Evelyn Price Index is below zero. The burner currently buys whenever an input is eligible, so it needs the existing reference-price policy before submitting a new purchase while preserving independent EVE burning.
## What Changes
- Permit new buybacks only with a fresh canonical EVE/USDT price strictly below the corresponding Evelyn status service's reference price at the current decision instant.
- Skip only the purchase when either price is unusable or the market price is at/above reference; continue existing EVE burn processing and re-evaluate next iteration.
- Preserve pending-burn priority, read-only pending-swap reconciliation, at most one new swap, and all existing amount, reserve, precision and transaction rules.
- Inject the Production Evelyn status service through the existing Hub composition, documenting its explicit startup dependency and the purchase-only policy.
- Update constructor/domain JavaDoc and operating documentation and verify the boundaries and recovery paths offline.
## Capabilities
### New Capabilities
None.
### Modified Capabilities
- `evelyn-iou-burner-service`: Gate new purchases on the existing reference-price API while keeping reconciliation and burns independent.
- `nenjim-hub-configuration`: Supply the corresponding Production status service to the burner using existing explicit dependency ordering.
## Impact
The burner constructor gains an `EvelynStatusService` dependency, supplied by `NenjimHubImpl`. Runtime input configuration, schedule, Ticker sources, history, ValueTags and live deployment configuration remain outside this change. Verification uses controlled offline collaborators without financial transactions or permanent test additions.
@@ -0,0 +1,71 @@
# Spec Delta
## MODIFIED Requirements
### Requirement: At most one confirmed swap attempt per iteration
After selecting a positive exact amount and satisfying the current below-reference price condition, the service SHALL invoke the existing Jupiter exact-input operation once with the selected CIS-resolved input mint, fixed EVE output mint, selected amount, and configured slippage. Normal return SHALL be treated as already `CONFIRMED` and SHALL NOT trigger a second confirmation wait. Once invoked, no later input currency SHALL be attempted in that iteration regardless of success or failure, and the service SHALL proceed to reload the complete EVE balance whenever processing was not interrupted.
A structured definitive on-chain swap failure SHALL be logged without suspending later-process swaps. A timed-out outcome or known-signature confirmation communication error SHALL retain process-local pending swap signature, canonical input, attempted amount and original validity metadata for later read-only reconciliation. Proven pre-submission errors SHALL permit a fresh attempt in a later scheduled iteration. An ambiguous post-submission error without a trustworthy signature SHALL retain manual suspension. Interruption SHALL preserve available pending context and propagate normally. No unknown outcome SHALL cause automatic rebuilding, re-signing or resubmission; pending swaps SHALL still permit existing EVE burn evaluation.
#### Scenario: First swap fails definitively
- **WHEN** the first attempted input returns a definitive on-chain failure
- **THEN** no second input is attempted in that iteration, the EVE balance is still reloaded, and a later iteration may attempt a new swap
#### Scenario: Swap outcome is unknown
- **WHEN** the attempted swap times out, throws an I/O failure that permits unknown post-submission status, or is interrupted
- **THEN** no equivalent or alternative swap is attempted while its outcome is unresolved; a known signature is checked in later iterations and a signature-less ambiguous submission requires manual reconciliation
#### Scenario: Swap returns normally
- **WHEN** Jupiter returns a successful result whose transaction already reached `CONFIRMED`
- **THEN** the burner performs no additional confirmation wait and reloads the wallet instead of deriving its burn amount only from the returned output amount
### Requirement: Production burner accepts USDT and SyrupUSDC
The production Hub SHALL configure USDT first with reserve 0.1, minimum input 0.05 and maximum input 0.25 USDT, and SyrupUSDC second with reserve 0.095, minimum input 0.045 and maximum input 0.2 SyrupUSDC. These SHALL be token-denominated limits without a USD-value guarantee. The production EVE burn minimum SHALL be 0.1 EVE and its retained reserve SHALL be 0.01 EVE, as selected by the owner on 2026-10-06, configured as MoneyAmount values using the canonical EVE UUID. The production Hub SHALL supply its corresponding Production Evelyn status service for current reference-price decisions. The existing burner wallet, Jupiter route selection, registration, hourly interval, slippage, EVE/USDT freshness, confirmation settings and burn recovery behavior SHALL be preserved without new Ticker sources or history storage.
#### Scenario: Production inputs and settings
- **WHEN** the Hub constructs the production burner
- **THEN** it supplies the exact reserves, minima and maxima as MoneyAmount values in USDT-then-SyrupUSDC priority, supplies minimum burn 0.1 EVE/reserve 0.01 EVE and the Production status service, and retains the other existing production arguments
#### Scenario: Production burn threshold
- **WHEN** production EVE balance is below 0.11, exactly 0.11, or 0.135 with usable mint precision and fresh price
- **THEN** below 0.11 produces no burn, 0.11 burns 0.1 and 0.135 burns 0.125; successful burns retain 0.01 EVE
## ADDED Requirements
### Requirement: New buybacks require a below-reference market price
An otherwise eligible new buyback SHALL require a fresh canonical EVE/USDT observation within the existing maximum price age and a usable canonical EVE/USDT reference price from the injected corresponding Evelyn status service at the current decision instant. Both prices SHALL be positive. Only actual price strictly below reference SHALL permit submission; equality SHALL not qualify. The existing public reference operation SHALL be reused without copying curve calculations or reading stored history.
#### Scenario: Strict boundary below reference
- **WHEN** an input is otherwise eligible and reference price is 15 USDT/EVE
- **THEN** market price 14.99 permits the existing buyback, while 15.00 and 15.01 submit no new swap from any input in that iteration
#### Scenario: Required prices are unusable
- **WHEN** market observation is missing, stale, incomplete, unavailable or has an invalid pair/non-positive price, or reference lookup throws, is missing or has an invalid pair/non-positive price
- **THEN** no new swap is submitted and a safe diagnostic explains why the purchase was skipped
#### Scenario: Reference uses the current decision instant
- **WHEN** the first usable input is ready for a new swap
- **THEN** the corresponding status service is asked for its reference price at the current instant rather than using a sampled history point or the observation timestamp
### Requirement: Price skips preserve independent burn processing and recovery
A rejected buyback price condition SHALL skip purchases only, continue complete EVE-balance processing under the existing independent burn requirements, and SHALL NOT create a suspension. Each subsequent otherwise eligible iteration SHALL re-evaluate prices. Pending-burn priority and read-only pending-swap reconciliation SHALL remain independent of the new-purchase condition; any newly permitted purchase after reconciliation SHALL pass the current price check.
#### Scenario: Existing EVE burns at or above reference
- **WHEN** market price is equal to or above reference and existing EVE satisfies its own reserve, minimum, precision, fresh valuation and transaction requirements
- **THEN** no new swap occurs and the existing eligible EVE is burned normally
#### Scenario: Reference unavailable but burn valuation is usable
- **WHEN** reference lookup is unavailable or invalid but existing EVE and its fresh canonical valuation satisfy the burn requirements
- **THEN** the purchase is skipped and the independent eligible burn still occurs
#### Scenario: Next scheduled iteration recovers
- **WHEN** one iteration skips a purchase because its prices do not qualify and a later otherwise eligible iteration has usable prices below reference
- **THEN** the later iteration can attempt its one new swap without a restart or manual reset
#### Scenario: Pending swap is resolved above reference
- **WHEN** a pending swap resolves read-only at or above reference
- **THEN** it is cleared normally, any otherwise eligible new purchase is price-checked and skipped, and existing EVE burn evaluation continues
#### Scenario: Unresolved swap and pending burn retain priority
- **WHEN** a swap remains unresolved or the iteration starts with a pending burn
- **THEN** existing transaction-priority rules apply without evaluating a new-purchase price condition or submitting a new swap
@@ -0,0 +1,48 @@
# Spec Delta
## MODIFIED Requirements
### Requirement: Selected processes are constructed and started lazily in exact order
The Hub SHALL support the modern process IDs `nenjim.registry.service`, `nenjim.journal.service`, `assetaz.ticker.default`, `jupiter-perps-alarm.default`, `evelyn.status.prod`, `evelyn.status.test`, `evelyn.iou-burner.prod`, `evelyn.liquidity.prod`, `nenjim.javafx-runtime.service`, `evelyn.mission-control.default`, and `nenjim.process-manager.default` through implementation-only construction capability that creates no process instance during validation. After passive composition, the Hub SHALL visit every configured entry after Registry in declared order, beginning with Journal. At each entry it SHALL construct only that process and any explicitly composed process-specific passive dependencies or administration view, register the process under the exact configured ID, resolve it through the canonical `NenjimProcess` contract where applicable, call `start()`, and record the ID only after successful return.
The production IOU burner SHALL receive the already constructed Production Evelyn status service, and SHALL require both Ticker and `evelyn.status.prod` to precede `evelyn.iou-burner.prod`. The configuration SHALL be the complete manually ordered process dependency closure. The Hub SHALL not discover, insert, recursively construct, reorder, or automatically start dependencies. A process omitted from `[AUTO_START]` SHALL not be constructed, registered, started, or recorded, even when its implementation is available. Legacy process prototypes outside the modern Hub graph SHALL not be selectable.
#### Scenario: Configured process starts successfully
- **WHEN** a configured process entry is reached and its dependencies are already available
- **THEN** that process is constructed, registered, started, and recorded before the next entry is reached
#### Scenario: Process is omitted
- **WHEN** a known process ID does not appear in `[AUTO_START]`
- **THEN** no instance of that process is constructed or registered and its lifecycle is never started or recorded
#### Scenario: Jupiter Perps Alarm is selected
- **WHEN** `jupiter-perps-alarm.default` is explicitly listed after its required predecessors
- **THEN** the otherwise inactive modern alarm process is constructed, registered, started and recorded at that exact position
#### Scenario: Dependency order is invalid
- **WHEN** a selected process is reached before a process dependency required by its current constructor or startup behavior
- **THEN** construction or startup fails clearly without implicit dependency construction, repair, or reordering
#### Scenario: JavaFX processes are omitted
- **WHEN** a valid headless plan omits `nenjim.javafx-runtime.service`, `evelyn.mission-control.default`, and `nenjim.process-manager.default`
- **THEN** none of those objects is constructed or registered and the JavaFX toolkit remains uninitialized by the Hub
#### Scenario: Renamed status services retain dependency wiring
- **WHEN** `evelyn.status.prod` and `evelyn.status.test` are listed after Ticker and before Mission Control
- **THEN** the Hub constructs separate Production/Test status services, registers the renamed IDs, and injects the corresponding typed service views into Mission Control in the configured order
#### Scenario: Deployment still contains an old status ID
- **WHEN** a private deployment configuration contains `evelyn.service.prod` or `evelyn.service.test`
- **THEN** validation rejects the unknown ID before startup; deployment migration replaces only that ID with `evelyn.status.prod` or `evelyn.status.test`, preserving selection and order
#### Scenario: Liquidity is explicitly selected
- **WHEN** `evelyn.liquidity.prod` is reached in a valid startup plan
- **THEN** the Hub loads its runtime configuration, binds the dedicated signer/wallet and Jupiter service to each other, constructs direct Raydium access and registers/starts the liquidity process without inserting a Ticker or status dependency or reordering the plan
#### Scenario: Production burner has its reference-price dependency
- **WHEN** `evelyn.iou-burner.prod` is reached after Ticker and `evelyn.status.prod`
- **THEN** the Hub injects the corresponding Production status service for buyback price decisions
#### Scenario: Production burner precedes its status dependency
- **WHEN** the burner is reached without a previously constructed Production status service
- **THEN** construction fails clearly without creating or starting the omitted dependency or the burner
@@ -0,0 +1,15 @@
# Tasks
## 1. Purchase policy and independent burns
- [x] 1.1 Require the corresponding Evelyn status service and gate a fully eligible new purchase on fresh canonical actual price strictly below its current reference; verify constructor validation, below/equal/above and unavailable/invalid prices with controlled offline checks.
- [x] 1.2 Update constructor/domain JavaDoc and Evelyn operating documentation; verify price skips still burn eligible existing EVE, re-evaluate next iteration and preserve pending burn/swap priority in the same offline checks.
## 2. Hub composition
- [x] 2.1 Inject the Production status dependency through the existing Hub guard and document the explicit Ticker/status/burner order; verify production arguments and fail-fast dependency behavior without starting the Hub or editing deployment configuration.
## 3. Integrated verification
- [x] 3.1 Compile main and existing test sources through normal Gradle/Detag, execute focused offline purchase/burn/recovery checks and relevant prior burner harnesses, and record their final results without adding permanent tests or running live transactions.
- [x] 3.2 Validate the scoped OpenSpec change strictly and check whitespace and changed-file scope; deliver completed planning artifacts and verification evidence for review.
@@ -0,0 +1,34 @@
# Verification
Verified on 2026-10-06 with `/usr/local/software/java/jfx-25`.
## Compilation and controlled acceptance checks
- `JAVA_HOME=/usr/local/software/java/jfx-25 ./gradlew compileJava compileTestJava --offline --no-daemon` → **BUILD SUCCESSFUL in 8s**. Normal Gradle-integrated Detag and both source compilations executed. The initial sandbox attempt could not create the existing Gradle cache lock outside the workspace; the same compilation passed with approved cache access.
- Temporary sources in `/tmp/evelyn-issue94` compiled with `javac --enable-preview --release 25 -cp 'build/classes/java/main:build/libs/*' -d /tmp/evelyn-issue94`.
- `java --enable-preview -cp '/tmp/evelyn-issue94:build/classes/java/main:build/libs/*' Issue94Verification` → **PASS: 459 focused issue #94 assertions**.
- The copied `Issue93Verification` → **PASS: 246 burn-policy regression assertions**.
- The copied `Issue92Verification` → **PASS: 115 input-minimum regression assertions**.
- The copied `Issue91Verification`, restricted to burner checks → **PASS: 80 pending-swap/recovery regression assertions**. Unchanged Solana/Jupiter library checks were not rerun.
- Production composition source check verifies the corresponding Production status dependency and preserved input reserves/minima/maxima, EVE burn minimum/reserve, hourly interval, slippage, freshness and finalization arguments.
- An INFO/WARN-enabled controlled run verifies purchase-skip reasons for at/above reference, unavailable/invalid reference and unusable market price, without arbitrary reference/Ticker exception messages.
The **900** controlled assertions invoke the actual burner iteration with offline wallet, chain, swap, Ticker, reference and notification collaborators. No RPC, signing, live financial operation, application/Hub startup or deployment configuration read occurs. The Hub dependency guard is invoked directly without constructing a Hub. No permanent automated tests were added. Prior harness copies only add an always-below reference stub to constructor calls and update #92's expected canonical EVE/USDT lookup count for eligible purchases; original temporary files remain intact.
The #94 harness covers 14.99/15.00/15.01 against reference 15, numeric equality across scales, a close below-reference decimal, the current reference decision instant instead of observation/history time, complete independent burns and reserve preservation, missing/unavailable/non-positive/null-amount/wrong-pair market and reference data, stale market observations, fresh independent burn valuation after a purchase-price failure, stale burn valuation postponement, next-iteration recovery from every rejection category, input priority and amount limits, below-minimum input fallback, no-eligible-input/direct-EVE-only paths, manual swap suspension and null status validation. It verifies original-signature read-only reconciliation while price is above reference, unresolved retention, definitive success/failure/proven expiry followed by a newly rejected purchase, later below-reference recovery, and simultaneous pending burn/swap priority with no reference lookup or new transaction. PriceObservation itself rejects null observation timestamp/price before they can reach the burner.
An initial temporary harness compilation used the wrong fully qualified component-ID type; it was corrected to the repository's existing `com.r35157.nenjim.service.registry.valuetypes.NenjimComponentId`. Final compiled checks pass. Concurrent initial Java invocations reported harmless performance-data lock warnings; the controlled diagnostic run disabled performance data. No production fix was needed for either verification-only issue.
## Review and workflow
Parent independent review of the proposal/specs/design, implementation, operating documentation and controlled harness found no actionable findings. The existing malformed burn JavaDoc line was corrected while updating that same list item. Scope is limited to the required reference dependency, new-purchase condition, Hub composition, related documentation and two OpenSpec capability deltas. Transaction execution, reconciliation, burn valuation/policy, ValueTags, scheduling and private deployment files retain their existing behavior.
Strict validation of the active change and `git diff --check` pass. All four planning artifact types and all five implementation tasks are complete. The active change is ready for review; main specifications have not been synchronized and the change has not been archived.
No deployment, commit, push, Gitea write or live integration was performed.
## Follow-up: clearer purchase-skip logs
The owner's requested logging refinement keeps price eligibility unchanged. INFO price skips now show a direct labelled comparison, for example `Skipping buyback as EVE price is at or above reference (market=15.01 >= reference=15 USDT/EVE)`, followed by the trading pair, decision instant and next action. Prices use plain decimals without redundant trailing zeros. WARN skips retain their reason; unavailable or invalid reference-price diagnostics also include the known market price.
`JAVA_HOME=/usr/local/software/java/jfx-25 ./gradlew compileJava --offline --no-daemon` passed. The existing temporary #94 harness passed its 459 assertions again with INFO/WARN enabled. Its captured output in `/tmp/evelyn-issue94/issue94-logging-refinement.log` confirms the numeric comparison for both equality and higher prices, reference failure details, missing/stale market diagnostics and exclusion of arbitrary exception messages. No new tests were added.
@@ -144,7 +144,7 @@ For each entry the service SHALL subtract its configured reserve and skip non-po
- **THEN** the service preserves interruption and ends processing without treating the input as an ordinary failure
### Requirement: At most one confirmed swap attempt per iteration
After selecting a positive exact amount, the service SHALL invoke the existing Jupiter exact-input operation once with the selected CIS-resolved input mint, fixed EVE output mint, selected amount, and configured slippage. Normal return SHALL be treated as already `CONFIRMED` and SHALL NOT trigger a second confirmation wait. Once invoked, no later input currency SHALL be attempted in that iteration regardless of success or failure, and the service SHALL proceed to reload the complete EVE balance whenever processing was not interrupted.
After selecting a positive exact amount and satisfying the current below-reference price condition, the service SHALL invoke the existing Jupiter exact-input operation once with the selected CIS-resolved input mint, fixed EVE output mint, selected amount, and configured slippage. Normal return SHALL be treated as already `CONFIRMED` and SHALL NOT trigger a second confirmation wait. Once invoked, no later input currency SHALL be attempted in that iteration regardless of success or failure, and the service SHALL proceed to reload the complete EVE balance whenever processing was not interrupted.
A structured definitive on-chain swap failure SHALL be logged without suspending later-process swaps. A timed-out outcome or known-signature confirmation communication error SHALL retain process-local pending swap signature, canonical input, attempted amount and original validity metadata for later read-only reconciliation. Proven pre-submission errors SHALL permit a fresh attempt in a later scheduled iteration. An ambiguous post-submission error without a trustworthy signature SHALL retain manual suspension. Interruption SHALL preserve available pending context and propagate normally. No unknown outcome SHALL cause automatic rebuilding, re-signing or resubmission; pending swaps SHALL still permit existing EVE burn evaluation.
@@ -294,11 +294,11 @@ The service SHALL select the lesser of positive `balance - minimumReserve` and t
- **THEN** the complete EVE balance is still evaluated and its rounded eligible amount above the EVE reserve is burned if it meets the EVE burn minimum
### Requirement: Production burner accepts USDT and SyrupUSDC
The production Hub SHALL configure USDT first with reserve 0.1, minimum input 0.05 and maximum input 0.25 USDT, and SyrupUSDC second with reserve 0.095, minimum input 0.045 and maximum input 0.2 SyrupUSDC. These SHALL be token-denominated limits without a USD-value guarantee. The production EVE burn minimum SHALL be 0.1 EVE and its retained reserve SHALL be 0.01 EVE, as selected by the owner on 2026-10-06, configured as MoneyAmount values using the canonical EVE UUID. The existing burner wallet, Jupiter route selection, registration, hourly interval, slippage, EVE/USDT freshness, confirmation settings and burn recovery behavior SHALL be preserved without new Ticker sources or history storage.
The production Hub SHALL configure USDT first with reserve 0.1, minimum input 0.05 and maximum input 0.25 USDT, and SyrupUSDC second with reserve 0.095, minimum input 0.045 and maximum input 0.2 SyrupUSDC. These SHALL be token-denominated limits without a USD-value guarantee. The production EVE burn minimum SHALL be 0.1 EVE and its retained reserve SHALL be 0.01 EVE, as selected by the owner on 2026-10-06, configured as MoneyAmount values using the canonical EVE UUID. The production Hub SHALL supply its corresponding Production Evelyn status service for current reference-price decisions. The existing burner wallet, Jupiter route selection, registration, hourly interval, slippage, EVE/USDT freshness, confirmation settings and burn recovery behavior SHALL be preserved without new Ticker sources or history storage.
#### Scenario: Production inputs and settings
- **WHEN** the Hub constructs the production burner
- **THEN** it supplies the exact reserves, minima and maxima as MoneyAmount values in USDT-then-SyrupUSDC priority, supplies minimum burn 0.1 EVE/reserve 0.01 EVE and retains the other existing production arguments
- **THEN** it supplies the exact reserves, minima and maxima as MoneyAmount values in USDT-then-SyrupUSDC priority, supplies minimum burn 0.1 EVE/reserve 0.01 EVE and the Production status service, and retains the other existing production arguments
#### Scenario: Production burn threshold
- **WHEN** production EVE balance is below 0.11, exactly 0.11, or 0.135 with usable mint precision and fresh price
@@ -336,3 +336,41 @@ The constructor SHALL accept minimumBurnAmount and eveReserve as EVE-denominated
#### Scenario: Stale EVE metadata and zero reserve
- **WHEN** both values carry the EVE UUID with stale names/symbols and the reserve is zero
- **THEN** construction succeeds and uses canonical EVE identity with the configured exact numeric amounts
### Requirement: New buybacks require a below-reference market price
An otherwise eligible new buyback SHALL require a fresh canonical EVE/USDT observation within the existing maximum price age and a usable canonical EVE/USDT reference price from the injected corresponding Evelyn status service at the current decision instant. Both prices SHALL be positive. Only actual price strictly below reference SHALL permit submission; equality SHALL not qualify. The existing public reference operation SHALL be reused without copying curve calculations or reading stored history.
#### Scenario: Strict boundary below reference
- **WHEN** an input is otherwise eligible and reference price is 15 USDT/EVE
- **THEN** market price 14.99 permits the existing buyback, while 15.00 and 15.01 submit no new swap from any input in that iteration
#### Scenario: Required prices are unusable
- **WHEN** market observation is missing, stale, incomplete, unavailable or has an invalid pair/non-positive price, or reference lookup throws, is missing or has an invalid pair/non-positive price
- **THEN** no new swap is submitted and a safe diagnostic explains why the purchase was skipped
#### Scenario: Reference uses the current decision instant
- **WHEN** the first usable input is ready for a new swap
- **THEN** the corresponding status service is asked for its reference price at the current instant rather than using a sampled history point or the observation timestamp
### Requirement: Price skips preserve independent burn processing and recovery
A rejected buyback price condition SHALL skip purchases only, continue complete EVE-balance processing under the existing independent burn requirements, and SHALL NOT create a suspension. Each subsequent otherwise eligible iteration SHALL re-evaluate prices. Pending-burn priority and read-only pending-swap reconciliation SHALL remain independent of the new-purchase condition; any newly permitted purchase after reconciliation SHALL pass the current price check.
#### Scenario: Existing EVE burns at or above reference
- **WHEN** market price is equal to or above reference and existing EVE satisfies its own reserve, minimum, precision, fresh valuation and transaction requirements
- **THEN** no new swap occurs and the existing eligible EVE is burned normally
#### Scenario: Reference unavailable but burn valuation is usable
- **WHEN** reference lookup is unavailable or invalid but existing EVE and its fresh canonical valuation satisfy the burn requirements
- **THEN** the purchase is skipped and the independent eligible burn still occurs
#### Scenario: Next scheduled iteration recovers
- **WHEN** one iteration skips a purchase because its prices do not qualify and a later otherwise eligible iteration has usable prices below reference
- **THEN** the later iteration can attempt its one new swap without a restart or manual reset
#### Scenario: Pending swap is resolved above reference
- **WHEN** a pending swap resolves read-only at or above reference
- **THEN** it is cleared normally, any otherwise eligible new purchase is price-checked and skipped, and existing EVE burn evaluation continues
#### Scenario: Unresolved swap and pending burn retain priority
- **WHEN** a swap remains unresolved or the iteration starts with a pending burn
- **THEN** existing transaction-priority rules apply without evaluating a new-purchase price condition or submitting a new swap
@@ -91,7 +91,7 @@ After validating the entire plan, the Hub SHALL construct the configured Registr
### Requirement: Selected processes are constructed and started lazily in exact order
The Hub SHALL support the modern process IDs `nenjim.registry.service`, `nenjim.journal.service`, `assetaz.ticker.default`, `jupiter-perps-alarm.default`, `evelyn.status.prod`, `evelyn.status.test`, `evelyn.iou-burner.prod`, `evelyn.liquidity.prod`, `nenjim.javafx-runtime.service`, `evelyn.mission-control.default`, and `nenjim.process-manager.default` through implementation-only construction capability that creates no process instance during validation. After passive composition, the Hub SHALL visit every configured entry after Registry in declared order, beginning with Journal. At each entry it SHALL construct only that process and any explicitly composed process-specific passive dependencies or administration view, register the process under the exact configured ID, resolve it through the canonical `NenjimProcess` contract where applicable, call `start()`, and record the ID only after successful return.
The configuration SHALL be the complete manually ordered process dependency closure. The Hub SHALL not discover, insert, recursively construct, reorder, or automatically start dependencies. A process omitted from `[AUTO_START]` SHALL not be constructed, registered, started, or recorded, even when its implementation is available. Legacy process prototypes outside the modern Hub graph SHALL not be selectable.
The production IOU burner SHALL receive the already constructed Production Evelyn status service, and SHALL require both Ticker and `evelyn.status.prod` to precede `evelyn.iou-burner.prod`. The configuration SHALL be the complete manually ordered process dependency closure. The Hub SHALL not discover, insert, recursively construct, reorder, or automatically start dependencies. A process omitted from `[AUTO_START]` SHALL not be constructed, registered, started, or recorded, even when its implementation is available. Legacy process prototypes outside the modern Hub graph SHALL not be selectable.
#### Scenario: Configured process starts successfully
- **WHEN** a configured process entry is reached and its dependencies are already available
@@ -125,6 +125,14 @@ The configuration SHALL be the complete manually ordered process dependency clos
- **WHEN** `evelyn.liquidity.prod` is reached in a valid startup plan
- **THEN** the Hub loads its runtime configuration, binds the dedicated signer/wallet and Jupiter service to each other, constructs direct Raydium access and registers/starts the liquidity process without inserting a Ticker or status dependency or reordering the plan
#### Scenario: Production burner has its reference-price dependency
- **WHEN** `evelyn.iou-burner.prod` is reached after Ticker and `evelyn.status.prod`
- **THEN** the Hub injects the corresponding Production status service for buyback price decisions
#### Scenario: Production burner precedes its status dependency
- **WHEN** the burner is reached without a previously constructed Production status service
- **THEN** construction fails clearly without creating or starting the omitted dependency or the burner
### Requirement: Configured startup is fail-fast and reports actual milestones
Registry and every selected process SHALL be registered before its `start()` call and appended to the Hub's immutable ordered startup snapshot only after `start()` returns successfully. Construction failure SHALL leave the selected process unregistered. Registration or startup failure SHALL stop the plan before any later entry is constructed or started; a startup failure MAY leave that process registered but SHALL not record it. Earlier successful processes SHALL remain in snapshots, no rollback or retry SHALL occur, and the Hub SHALL announce its existing online point and enter its blocking runtime wait only after every configured process succeeds.