unrip/PROOF.md
philipp 7ea1576ba7 Plan quote lifecycle truth turn
Proof: Archive the completed runtime-health turn and open a new implementation turn that replaces ambiguous quote verdicts with explicit lifecycle truth and durable execution explanation.

Assumptions: Recent decision and execution records already contain enough repo-owned evidence to derive a truthful first-pass quote lifecycle for the active pair.

Still fake: The new turn is planning state only; the dashboard still contains the existing lifecycle ambiguity until this proof is implemented.
2026-04-09 00:39:02 +02:00

154 lines
7.4 KiB
Markdown

# Implementation Proof: quote lifecycle truth and execution explanation
Status: open
Opened: 2026-04-09
## Target outcome
This turn proves that `unrip` can explain every quote outcome in operator-visible, durable terms instead of forcing the operator to infer meaning from ambiguous labels.
The concrete target is the live NEAR Intents BTC/EURe system:
- each quote row must expose its current lifecycle state
- each non-trade outcome must expose the decisive reason code
- execution submission must be distinguishable from strategy approval
- blocked, rejected, submitted, failed, and not-filled paths must be visibly different
- quote identifiers must be directly usable by operators for tracing and support
## Why this is a meaningful architecture test
The current operator surface still fails a core thesis requirement:
- the Strategy page shows `Actionable`, which does not tell the operator whether a trade was actually submitted
- an operator looking at one quote cannot answer, at a glance, why it did or did not become a trade
- quote ids are hidden behind truncation with no direct copy affordance
- execution truth exists durably in PostgreSQL, but the UI does not surface the lifecycle coherently
That is not just a copy problem. It is an observability gap in the trading product itself. If the system cannot explain a quote outcome precisely, execution is outrunning observability.
## Hypothesis
`unrip` becomes more trustworthy if quote handling is modeled and rendered as an explicit lifecycle instead of a single strategy verdict:
- strategy evaluation is only one stage in the lifecycle
- executor acceptance or rejection must be first-class state
- venue submission and downstream outcome must be represented separately
- durable reason codes must drive operator labels
- forbidden labels that collapse multiple meanings, especially `Actionable`, must be removed
The turn passes only if an operator can inspect a quote and immediately understand whether it was filtered, rejected, blocked, submitted, failed, awaiting venue outcome, not filled, or completed, and why.
## Scope
- [I021] Quote lifecycle truth and execution explanation: replace ambiguous dashboard verdicts with a per-quote state machine that shows exactly why a quote was filtered, rejected, blocked, submitted, not filled, or executed, with durable reason codes and operator-facing traceability.
- Cover the live path from:
- raw or normalized quote observation
- strategy decision
- execute-trade command emission
- executor result
- solver relay or venue outcome where available
- Update the dashboard surfaces that currently expose quote or strategy truth:
- Strategy page
- any quote or recent-decision tables tied to the active pair
- quote-id presentation and operator trace affordances
## Assumptions
- The existing durable stores already contain enough information for at least the current live path through strategy decision and executor result.
- Some downstream venue-outcome states may still be partially fake or unavailable for older rows; if so, the UI must say that plainly rather than implying more certainty.
- The immediate turn should prioritize truthful lifecycle explanation over broader analytics such as markout or long-window outcome attribution.
## Turn-shaping rules
- `Actionable` is forbidden as an operator-facing state or label.
- Do not add a second analytics product. Stay focused on per-quote lifecycle truth for the live active pair.
- Do not invent lifecycle states that cannot be backed by durable repo-owned evidence.
- If a state transition is inferred rather than durably observed, the UI must make that distinction explicit.
- Prefer a small, explicit state machine over a long list of loosely related badges.
## Non-goals
- No new venue integrations.
- No broad historical markout analytics turn.
- No new execution automation or risk widening.
- No redesign of the entire dashboard visual system beyond what is needed to make the quote lifecycle understandable.
## Required operator behavior
### Lifecycle truth
For each visible quote or decision row, the operator must be able to identify the current lifecycle state from a bounded set such as:
- `Filtered`
- `Rejected by strategy`
- `Blocked before submit`
- `Submission failed`
- `Submitted`
- `Awaiting venue outcome`
- `Not filled` or equivalent final non-fill state, if durable evidence exists
- `Completed` or equivalent successful terminal state, if durable evidence exists
Exact labels may vary, but they must be specific and mutually meaningful.
### Reason truth
Each non-terminal or terminal non-trade state must expose a clear decisive reason, such as:
- unsupported pair
- below edge threshold
- inventory unavailable
- executor disarmed
- executor paused
- submission failed
- venue timeout
- quote expired
If the decisive reason is not known, the surface must say that plainly instead of inventing confidence.
### Traceability
For each quote row the operator must be able to access:
- quote id in a non-hidden, copyable form
- decision id where present
- command id where present
- execution result where present
- pair and direction
The operator must be able to reason from a single row without manually cross-correlating multiple pages.
### UI language
The UI must not render `Actionable`.
Any replacement label must answer a concrete operator question, such as:
- did strategy approve this?
- was a command emitted?
- was the command blocked?
- was it submitted?
- did it fail?
## Definition of done
- `Actionable` is removed from operator-facing dashboard surfaces.
- A durable quote lifecycle model exists in repo-owned code and is used by the dashboard.
- At least the current live quote path through strategy decision and executor result is rendered coherently per quote.
- The operator can tell, from one row, why a recent quote did or did not turn into a submitted trade.
- Quote ids are copyable and clearly visible enough for tracing.
- Regression tests cover at least:
- strategy-approved but executor-disarmed rows
- submitted rows
- forbidden ambiguous label removal
For this turn to close with status `passed`, the specific operator question:
`Why did this quote not trade?`
must be answerable directly from the dashboard for recent rows without needing manual database inspection.
## Validation evidence required
- direct UI or bootstrap evidence that recent rows show explicit lifecycle states instead of `Actionable`
- direct evidence that a strategy-approved but executor-disarmed row renders as blocked or rejected with reason
- direct evidence that a submitted row renders as submitted
- direct evidence that quote ids are directly usable for tracing
- automated test evidence for lifecycle derivation and dashboard rendering
## Failure conditions
- `Actionable` still appears in the dashboard
- the operator still cannot distinguish strategy approval from execution submission
- non-trade rows still lack a decisive reason
- quote ids remain hidden or non-copyable
- lifecycle labels are only cosmetic and not backed by durable repo-owned state
## Current real before this turn
- strategy decisions are stored durably
- execution results are stored durably
- command ids, decision ids, and quote ids already exist in the durable path
- the operator dashboard already serves recent decisions and execution-adjacent state
## Deliberately not built by this proof
- full venue settlement attribution for all historic trades
- generalized quote analytics beyond lifecycle explanation
- multi-venue lifecycle harmonization