104: EMC Perps: show estimated Jupiter Value and mark affected totals with ≈
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-10-26
|
||||
@@ -0,0 +1,29 @@
|
||||
# Design
|
||||
|
||||
## Context
|
||||
|
||||
See proposal.md for motivation. Jupiter already parses optional micro-USD fields through strict decimal-integer validation. Immutable snapshot Metrics own completeness-aware totals; venue totals add isolated positions and shared Cross accounts once. EMC formats those totals independently of visible descendants.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:** Carry numeric Value and its estimate provenance together through the existing pipeline, preserving original observation/failure semantics and source compatibility for existing constructors.
|
||||
|
||||
**Non-Goals:** Correcting Jupiter fees, verifying closing proceeds, adding network requests, changing Phoenix valuation formulas, or modifying refresh/configuration.
|
||||
|
||||
## Decisions
|
||||
|
||||
- Extend the overview position with nullable USD Value, using the existing exact micro-USD parser. Retain earlier constructors with unavailable Value defaults. An independent decimal parser would risk a different validation contract.
|
||||
- Add an immutable set of Value estimate sources to Metrics (Jupiter/Phoenix). Mark each integration's available closing Values and union sources in totals. A single boolean would lose the source-specific explanation at mixed wallet/root levels; deriving qualification from rendered descendants would fail when groups are hidden/collapsed.
|
||||
- Estimate sources survive incomplete totals so their tooltips can still explain the contributions. Numeric availability controls whether a marker is shown. Totals still apply the existing all-components-required rule. Empty sums remain zero. Source sets do not affect other metrics or Cross account ownership.
|
||||
- Format Value with a single prefix only for available qualified amounts. Add source explanations to the Value cell tooltip from its Metrics, so ancestors do not depend on descendant notes. Preserve the existing position notes, read status and USD rounding.
|
||||
- Verify with temporary deterministic HTTP/service/JavaFX harnesses outside the repository, following the project's separate test-artifact policy. Record checks in verification.md.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- Reported Jupiter estimates may differ materially from closing proceeds → use the number as supplied and describe observed fee uncertainty plus unverified collateral/profit-cap semantics at contributing scopes.
|
||||
- Losing qualification during aggregation → keep provenance in immutable Metrics and verify mixed, missing, zero and collapsed totals.
|
||||
- Mistaking retained values for new observations → keep the existing whole-venue retention path and verify original timestamps through failure/recovery.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
No stored schema or configuration migration. Rebuild the existing source; retained constructors support current callers. Deploy/restart remains outside this implementation task. Reverting the source restores the previous presentation.
|
||||
@@ -0,0 +1,29 @@
|
||||
# Proposal
|
||||
|
||||
## Why
|
||||
|
||||
Evelyn's capital overview currently hides Jupiter's reported position Value and every dependent total. Issue #104 requests the venue estimate with an explicit approximation qualification so the owner can inspect capital without mistaking it for guaranteed closing proceeds.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Preserve nullable Jupiter `valueUsd`, converting integer micro-USD exactly without fee corrections.
|
||||
- Carry immutable Value estimate sources through complete, account-aware totals, including Phoenix's existing closing estimates.
|
||||
- Display available estimates and affected totals with one `≈`, two USD decimals and source-specific explanations; incomplete totals remain `—`.
|
||||
- Preserve polling, failure retention, observation times, Cross capital accounting and independent position metrics.
|
||||
- Update current project and shared Evelyn documentation, preserving the valuation uncertainties.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
None.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `jupiter-perps-overview`: Preserve the reported estimate and validate its optional integer amount.
|
||||
- `evelyn-perps-service`: Publish estimate sources and propagate them through complete totals and retained observations.
|
||||
- `evelyn-perps-overview`: Format approximate Value and explain Jupiter/Phoenix contributions at every level.
|
||||
|
||||
## Impact
|
||||
|
||||
Changes affect the Jupiter overview position record/reader, Perps snapshot/service, EMC Value presentation, `docs/JupiterPerpsOverview.md`, `docs/Evelyn.md` and the canonical shared Evelyn page in `r35157_docs`. Existing constructors remain available. No new endpoint, price source, dependency, signing or trading operation is introduced. Implementation remains uncommitted and unpushed.
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Estimated Value is visibly qualified at every level
|
||||
Available estimated Value SHALL show one `≈` before USD formatting with two decimals, including signed/zero values and every affected venue, wallet and root total. Unavailable Value SHALL show `—` without a numeric approximation marker. Tooltips SHALL identify contributing estimate sources and distinguish estimates from actual closing proceeds. Existing Phoenix account calculations and all independent columns SHALL remain intact.
|
||||
|
||||
#### Scenario: Jupiter position tooltip
|
||||
- **WHEN** the owner inspects Jupiter position Value
|
||||
- **THEN** its tooltip says "Estimated position value reported by Jupiter. Actual proceeds on closing may differ."
|
||||
- **AND** it explains the observed opening-fee treatment uncertainty and unverified collateral/profit-cap semantics without claiming differences are always small or every response is wrong
|
||||
|
||||
#### Scenario: Rounding and affected ancestors
|
||||
- **WHEN** a Jupiter position Value is 123.234567 USD
|
||||
- **THEN** its Value displays `≈$123.23`
|
||||
- **AND** Jupiter, wallet and root totals each display one `≈` and explain the Jupiter contribution, even when collapsed
|
||||
|
||||
#### Scenario: Phoenix and incomplete totals
|
||||
- **WHEN** Phoenix estimates contribute to a mixed portfolio
|
||||
- **THEN** available affected totals also explain Phoenix's estimated closing Value
|
||||
- **AND** a missing required contribution leaves the affected total `—` without `≈`
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Value estimates preserve their sources through totals
|
||||
Snapshots SHALL preserve Jupiter's reported Value and identify available Jupiter and Phoenix Values as estimates. Every complete Value total SHALL inherit its contributing estimate sources independently of UI expansion. Missing required values SHALL keep totals unavailable. Cross capital SHALL count once. Failed reads SHALL retain the prior values, qualifications and original times with failure status; success SHALL replace them.
|
||||
|
||||
#### Scenario: Mixed complete totals
|
||||
- **WHEN** a wallet has a Jupiter estimate of 12 USD and a Phoenix Cross account estimate of 84 USD with multiple children
|
||||
- **THEN** wallet and root Value are 96 USD and identify both estimate sources
|
||||
- **AND** collapsing any group changes neither total nor qualification
|
||||
|
||||
#### Scenario: Missing contribution and successful empty scope
|
||||
- **WHEN** a required Jupiter Value is missing
|
||||
- **THEN** the dependent Value totals remain unavailable without losing other metrics
|
||||
- **AND** a successfully read empty scope can still contribute zero
|
||||
|
||||
#### Scenario: Failed estimate and recovery
|
||||
- **WHEN** a valid Jupiter estimate is followed by a malformed observation
|
||||
- **THEN** the original estimate, its qualification and success/observation times remain with failure status
|
||||
- **AND** successful subsequent observations replace the estimate, including replacing it with missing Value or clearing an empty scope
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Verified metrics and unavailable valuations
|
||||
The overview SHALL preserve size basis, post-fee USD collateral and price PnL before separate fees, with leverage/ROI against positive collateral. It SHALL preserve optional reported `valueUsd` as an unverified estimate, converting integer micro-USD exactly without fee corrections. Missing/null Value SHALL remain unavailable; present malformed amounts SHALL fail the observation. Other valid metrics SHALL survive missing Value.
|
||||
|
||||
#### Scenario: Unverified API closing value
|
||||
- **WHEN** API Value subtracts opening fees already settled in collateral or does not establish profit-cap valuation
|
||||
- **THEN** the reported Value is preserved unchanged as an unverified estimate while independent metrics remain available
|
||||
- **AND** it is not represented as guaranteed closing proceeds or corrected by adding opening fees back
|
||||
|
||||
#### Scenario: Reported API closing estimate
|
||||
- **WHEN** Jupiter reports `valueUsd` as `"123234567"`, `"0"` or `"-1234567"`
|
||||
- **THEN** the overview preserves exactly 123.234567, 0 or -1.234567 USD respectively
|
||||
- **AND** it does not add opening fees back or impose a profit-cap correction
|
||||
|
||||
#### Scenario: Missing or malformed Value
|
||||
- **WHEN** `valueUsd` is missing or null
|
||||
- **THEN** Value is unavailable while independent metrics remain available
|
||||
- **AND** a present malformed amount instead fails the complete observation
|
||||
|
||||
#### Scenario: Nonpositive collateral
|
||||
- **WHEN** a position's collateral is zero or negative
|
||||
- **THEN** its leverage and PnL percentage are unavailable
|
||||
@@ -0,0 +1,20 @@
|
||||
# Tasks
|
||||
|
||||
## 1. Exact Jupiter estimate observation
|
||||
|
||||
- [x] 1.1 Preserve nullable reported Value through the overview record/reader; verify exact micro-USD conversion, large/signed/zero/missing/null amounts and malformed observation rejection with temporary fixtures.
|
||||
- [x] 1.2 Update JupiterPerpsOverview.md with the reported-estimate contract and historical fee uncertainty; verify obsolete unavailable-only claims are removed.
|
||||
|
||||
## 2. Immutable estimate provenance and complete totals
|
||||
|
||||
- [x] 2.1 Map Jupiter and Phoenix estimate sources into immutable Metrics and propagate complete totals; verify Jupiter/wallet/root and mixed Cross totals, missing components, empty scopes and source immutability.
|
||||
- [x] 2.2 Verify real service failure/retention/recovery using deterministic fixtures, including original timestamps, replacement by missing Value and empty scope clearing; record results in verification.md.
|
||||
|
||||
## 3. EMC Value presentation and current documentation
|
||||
|
||||
- [x] 3.1 Format available estimated Value with one approximation prefix and source-specific tooltips; verify USD rounding, signed/zero/missing values, ancestor tooltips, collapsed groups and retained/recovered rows in a temporary JavaFX harness.
|
||||
- [x] 3.2 Update docs/Evelyn.md and r35157_docs/projects/evelyn/README.md; verify estimate limitations, source links and consistency with the implementation.
|
||||
|
||||
## 4. Integration validation
|
||||
|
||||
- [x] 4.1 Run Gradle build and strict OpenSpec validation, inspect the final diff and record verification evidence; confirm no implementation commit/push and preserve pre-existing changes.
|
||||
@@ -0,0 +1,26 @@
|
||||
# Verification — issue #104
|
||||
|
||||
Verified locally on 2026-10-26. Implementation remains uncommitted and unpushed.
|
||||
No deployment, Hub restart, signing, trading, new venue request or price source.
|
||||
|
||||
## Delivered behavior
|
||||
|
||||
- The existing Jupiter overview GET preserves optional `valueUsd` as an exact decimal conversion from integer micro-USD. Zero, signed and large values survive; missing/null remains unavailable and malformed fields fail the complete observation. The reported number is used unchanged.
|
||||
- Immutable Metrics carry Jupiter/Phoenix estimate sources through account-aware venue, wallet and root totals. Sources are defensively copied. Shared Cross balances are counted once and position-only Cross Value remains inapplicable. Incomplete totals remain unavailable; their tooltips still explain the contributing estimate sources.
|
||||
- Available estimated Value displays one `≈` before the existing USD formatting and two-decimal rounding. Missing values show `—` without a numeric marker. Source-specific Value tooltips explain Jupiter's reported estimate and valuation uncertainty, Phoenix's estimated closing Value, and the difference from actual closing proceeds.
|
||||
- Whole-venue failure retention keeps original positions, source qualifications, observation time and last-success time. Successful recovery replaces observations, including replacing old Value with missing Value or clearing a successful empty scope. No polling/request/configuration behavior changed.
|
||||
- Current repository documentation and `r35157_docs/projects/evelyn/README.md` describe the new behavior and retain the real valuation limitations. The three affected main OpenSpec specifications are synced. Historical archived #100 documentation remains historical.
|
||||
|
||||
## Checks
|
||||
|
||||
- `JAVA_HOME=/usr/local/software/java/jfx-25 ./gradlew build`: successful; 42 existing tests, zero failures/errors/skips.
|
||||
- `/tmp/Issue104Check.java`: 63 focused assertions passed against the actual Jupiter HTTP reader, immutable model and background service using local HTTP fixtures. Covers exact `123234567 → 123.234567`, zero/negative/above-binary-integer-precision amounts, missing/null, eleven malformed representations, unchanged historical fee example, stable independent metrics, Jupiter and mixed totals, Cross and isolated Phoenix, defensive source copies, failure retention and replacement/empty recovery.
|
||||
- `/tmp/Issue104Preview.java`: 60 JavaFX assertions passed against actual table cells and tooltips. This is an assertion count, not 60 distinct user scenarios. Covers `≈$123.23`, `≈$0.00`, `≈-$1.23`, half-up rounding and tiny negative rounding to unsigned zero; complete and unavailable ancestor totals; Jupiter/Phoenix source explanations; Cross accounting; collapsed venue/Cross/wallet/root groups; unchanged rows/selection; retained/read-failed/recovered observations; empty and unknown hidden venues; independent Exposure/Collateral/Leverage/uPnL/Risk/TWAP and direction styles; horizontal scrolling.
|
||||
- Visually inspected `/tmp/issue104-check/value-expanded.png`, `value-collapsed.png`, `value-incomplete.png`, `value-total-tooltip.png` and `value-small-window.png`. Value was horizontally scrolled into the viewport before the final captures; the mixed tooltip is readable and bounded.
|
||||
- Existing temporary `/tmp/Issue102Check.java` and `/tmp/Issue103Check.java` passed their 68 risk and 32 TWAP assertions respectively. No permanent test sources or dependencies were added.
|
||||
- Strict validation passes for `104-jupiter-estimated-value` and main specifications `jupiter-perps-overview`, `evelyn-perps-service` and `evelyn-perps-overview`. Existing long paragraphs in the overview specification emit informational length hints only.
|
||||
- Working-tree and change-artifact whitespace checks pass, and all 22 local documentation links resolve, including the new Jupiter section anchor. The 22 pre-existing staged/deleted OpenSpec artifacts for #97, #99 and #103 remain untouched; no issue-104 file was staged.
|
||||
|
||||
## Limits
|
||||
|
||||
Verification uses deterministic local fixtures, not live closing quotes or deployment to the running Hub. It establishes the reported-value pipeline, qualification and retention behavior, not correctness of Jupiter's valuation or equality with actual closing proceeds. The 24 October fee example in the Jupiter documentation is a preserved historical observation.
|
||||
@@ -147,3 +147,21 @@ Warning tooltips SHALL identify wallet/account/position, reason, TWAP address, a
|
||||
- **WHEN** a warned venue or consumer read fails, or its original observation becomes five minutes old
|
||||
- **THEN** source and inherited warnings remain visible with retained/stale qualification and original times
|
||||
- **AND** existing UI polling updates age without additional venue reads or resetting selection and expansion
|
||||
|
||||
### Requirement: Estimated Value is visibly qualified at every level
|
||||
Available estimated Value SHALL show one `≈` before USD formatting with two decimals, including signed/zero values and every affected venue, wallet and root total. Unavailable Value SHALL show `—` without a numeric approximation marker. Tooltips SHALL identify contributing estimate sources and distinguish estimates from actual closing proceeds. Existing Phoenix account calculations and all independent columns SHALL remain intact.
|
||||
|
||||
#### Scenario: Jupiter position tooltip
|
||||
- **WHEN** the owner inspects Jupiter position Value
|
||||
- **THEN** its tooltip says "Estimated position value reported by Jupiter. Actual proceeds on closing may differ."
|
||||
- **AND** it explains the observed opening-fee treatment uncertainty and unverified collateral/profit-cap semantics without claiming differences are always small or every response is wrong
|
||||
|
||||
#### Scenario: Rounding and affected ancestors
|
||||
- **WHEN** a Jupiter position Value is 123.234567 USD
|
||||
- **THEN** its Value displays `≈$123.23`
|
||||
- **AND** Jupiter, wallet and root totals each display one `≈` and explain the Jupiter contribution, even when collapsed
|
||||
|
||||
#### Scenario: Phoenix and incomplete totals
|
||||
- **WHEN** Phoenix estimates contribute to a mixed portfolio
|
||||
- **THEN** available affected totals also explain Phoenix's estimated closing Value
|
||||
- **AND** a missing required contribution leaves the affected total `—` without `≈`
|
||||
|
||||
@@ -119,3 +119,21 @@ Snapshots SHALL preserve isolated risk prices and Cross account tiers/thresholds
|
||||
- **WHEN** isolated distance reaches/crosses zero or effective collateral is nonpositive
|
||||
- **THEN** the signed boundary is preserved or MM percentage is unavailable respectively
|
||||
- **AND** display rounding does not determine risk classification
|
||||
|
||||
### Requirement: Value estimates preserve their sources through totals
|
||||
Snapshots SHALL preserve Jupiter's reported Value and identify available Jupiter and Phoenix Values as estimates. Every complete Value total SHALL inherit its contributing estimate sources independently of UI expansion. Missing required values SHALL keep totals unavailable. Cross capital SHALL count once. Failed reads SHALL retain the prior values, qualifications and original times with failure status; success SHALL replace them.
|
||||
|
||||
#### Scenario: Mixed complete totals
|
||||
- **WHEN** a wallet has a Jupiter estimate of 12 USD and a Phoenix Cross account estimate of 84 USD with multiple children
|
||||
- **THEN** wallet and root Value are 96 USD and identify both estimate sources
|
||||
- **AND** collapsing any group changes neither total nor qualification
|
||||
|
||||
#### Scenario: Missing contribution and successful empty scope
|
||||
- **WHEN** a required Jupiter Value is missing
|
||||
- **THEN** the dependent Value totals remain unavailable without losing other metrics
|
||||
- **AND** a successfully read empty scope can still contribute zero
|
||||
|
||||
#### Scenario: Failed estimate and recovery
|
||||
- **WHEN** a valid Jupiter estimate is followed by a malformed observation
|
||||
- **THEN** the original estimate, its qualification and success/observation times remain with failure status
|
||||
- **AND** successful subsequent observations replace the estimate, including replacing it with missing Value or clearing an empty scope
|
||||
|
||||
@@ -18,11 +18,22 @@ The overview SHALL read the official positions response for one wallet, validate
|
||||
- **THEN** the successful result clears that wallet's Jupiter scope
|
||||
|
||||
### Requirement: Verified metrics and unavailable valuations
|
||||
The overview SHALL preserve size basis, use post-fee USD collateral and price PnL before separate fees, and calculate leverage and ROI against positive collateral. Unverified closing valuations SHALL be unavailable with an explanation; placeholder zeros and double subtraction of settled fees SHALL NOT be used.
|
||||
The overview SHALL preserve size basis, post-fee USD collateral and price PnL before separate fees, with leverage/ROI against positive collateral. It SHALL preserve optional reported `valueUsd` as an unverified estimate, converting integer micro-USD exactly without fee corrections. Missing/null Value SHALL remain unavailable; present malformed amounts SHALL fail the observation. Other valid metrics SHALL survive missing Value.
|
||||
|
||||
#### Scenario: Unverified API closing value
|
||||
- **WHEN** API value subtracts opening fees already settled in collateral or does not establish profit-cap valuation
|
||||
- **THEN** closing Value is unavailable, while independently verified metrics remain available
|
||||
- **WHEN** API Value subtracts opening fees already settled in collateral or does not establish profit-cap valuation
|
||||
- **THEN** the reported Value is preserved unchanged as an unverified estimate while independent metrics remain available
|
||||
- **AND** it is not represented as guaranteed closing proceeds or corrected by adding opening fees back
|
||||
|
||||
#### Scenario: Reported API closing estimate
|
||||
- **WHEN** Jupiter reports `valueUsd` as `"123234567"`, `"0"` or `"-1234567"`
|
||||
- **THEN** the overview preserves exactly 123.234567, 0 or -1.234567 USD respectively
|
||||
- **AND** it does not add opening fees back or impose a profit-cap correction
|
||||
|
||||
#### Scenario: Missing or malformed Value
|
||||
- **WHEN** `valueUsd` is missing or null
|
||||
- **THEN** Value is unavailable while independent metrics remain available
|
||||
- **AND** a present malformed amount instead fails the complete observation
|
||||
|
||||
#### Scenario: Nonpositive collateral
|
||||
- **WHEN** a position's collateral is zero or negative
|
||||
|
||||
Reference in New Issue
Block a user