# 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 - operator-facing labels must not overclaim beyond the durable evidence actually stored ## 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. The immediate trigger for this turn is a real semantic failure: - the dashboard treated `trade_execution_results.status = submitted` as a successful trade - recent submitted quote terms were rendered as if they were realized asset deltas - tests passed because that wrong assumption had been encoded into the test suite itself This turn must therefore fix both the UI and the conditions that allowed the mistake through. ## 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. - The prevention strategy must be implemented in repo code and tests rather than left to reviewer judgment alone. ## Turn-shaping rules - `Actionable` is forbidden as an operator-facing state or label. - Operator-facing labels must not overstate event certainty. - Terms such as `trade`, `success`, `filled`, `completed`, `profit`, and `asset delta` are forbidden unless backed by a durable event explicitly representing that fact. - 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. The repo must adopt a hard evidence-state vocabulary for this turn. At minimum: - `observed` - `evaluated` - `command_emitted` - `rejected` - `blocked` - `submitted` - `failed` - `awaiting_outcome` - `completed` No operator surface may collapse these into softer or stronger claims. ### 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? ### Semantic invariants The implementation and tests must enforce at least these invariants: - `submitted` is not `completed` - `submitted` is not a realized asset delta - executor-side blocking is not strategy rejection - stronger labels must not be rendered from weaker evidence These invariants are proof-critical, not optional cleanup. ## 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. - overloaded backend and UI names that imply stronger certainty than the evidence supports are removed or renamed - Regression tests cover at least: - strategy-approved but executor-disarmed rows - submitted rows - forbidden ambiguous label removal - forbidden semantic overclaims such as treating `submitted` as `completed` 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 - automated test evidence for negative semantic invariants, especially `submitted != completed` ## 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 - the repo still uses `trade` or `asset delta` language for mere submission evidence - tests still encode the old overclaiming semantics ## 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 ## Prevention requirements for this proof - Add a truth-review checklist to the implementation work: - what exact durable table or event backs this label? - what is the strongest claim the evidence supports? - what would make this wording false? - what negative regression test prevents that overclaim from returning? - Separate lifecycle derivation from summary metrics so summaries are computed from lifecycle states rather than raw convenience queries.