# Implementation Proof: Quote lifecycle investigator and missed quote follow-up Status: open Opened: 2026-06-12 ## Hypothesis If the operator dashboard turns the quote lifecycle table into a durable quote investigator, an operator can pause or filter the live quote list, select an `Awaiting executor` or otherwise missed quote, and continue following that exact quote through command, executor result, relay failure, outcome, or unresolved state even after the rolling live table moves on. ## Problem Evidence - The current Quote lifecycle page is a rolling live table of recent rows. - Pausing freezes the displayed table snapshot, including stale `Awaiting executor` evidence. - When live updates resume, the quote can leave the recent window and become hard to find again. - The existing expandable row explains the lifecycle only while the row remains in the rendered recent set. - This prevents practical investigation of missed quotes such as commands that later become `quote_not_found_or_finished`, `verifier_salt_unavailable`, stale command rejects, or successful submissions. ## Scope - Improve the existing `Quote lifecycle` dashboard view, not a new dashboard product area. - Add a durable quote lookup path by `quote_id`, `decision_id`, or `command_id` using existing history tables. - Add a selected or pinned quote investigator that remains visible independently from the rolling table rows. - Make pause freeze table ordering only; the selected quote investigation must still refresh from durable evidence. - Add search or lookup controls so a quote can be found again after it leaves the recent table. - Add filters for investigation states that matter to missed quotes: - awaiting executor - approved but command missing - blocked before submit - submission failed - quote not found or finished - strategy rejected - submitted or awaiting outcome - Improve the selected quote detail so `Awaiting executor` clearly shows: - command id and command timestamp - elapsed time since command - whether an executor result is now stored - relay result or block reason if present - next expected stage when still unresolved - Preserve old executor result and lifecycle rows as readable when newer timing or result fields are missing. - Keep the implementation read-side and dashboard-only unless a small shared lifecycle normalizer change is required. ## Non-goals - Do not change strategy selection, pricing, edge thresholds, notional limits, inventory checks, arming, signer identity, or pair enablement. - Do not skip quotes or alter executor/relay response behavior. - Do not add active pair, edge, notional, latency, response-policy, or retention environment variables. - Do not add a new retention policy or new long-term analytics store in this turn. - Do not build the full remaining analytics workbench: quote volume windows, size-bucket distributions, oracle-deviation views, and matched-only PnL analytics remain backlog work. - Do not claim submitted quote responses are completed trades unless durable outcome and settlement evidence support that claim. - Do not use manual kubectl rollout, image patching, or ad hoc production repair. ## Definition of Done - The Quote lifecycle page has a stable selected or pinned quote investigator separate from the rolling table rows. - Selecting an `Awaiting executor` row lets the operator continue following that quote after the table is paused, resumed, filtered, or updated. - A selected quote can be refreshed or auto-refreshed from durable evidence even when it is no longer present in `recent_lifecycle_rows`. - Lookup by `quote_id`, `decision_id`, or `command_id` returns the same normalized lifecycle shape used by the table, including stage timestamps, reason text, timing, command, execution result, and outcome fields when present. - Problem-state filters make missed quote rows easy to isolate without hiding the selected quote investigation. - Rows with missing old fields render as unavailable instead of crashing or disappearing. - Bug regression coverage proves: - a selected quote remains inspectable after it leaves the recent live list - an `Awaiting executor` row can later refresh into a terminal executor or relay result - lookup by quote, decision, and command identifiers uses durable evidence and does not rely only on the current client-side recent rows - Targeted dashboard tests pass. - Full `npm test` passes. - The operator dashboard bundle builds. - The planning and implementation commits include `Proof:`, `Assumptions:`, and `Still fake:`. - If tests pass, deploy only through the repo push workflow and collect live evidence: - repo-owned deployments are on the new image - Quote lifecycle still receives live rows - at least one durable quote lookup returns a lifecycle row - a missed or pending quote can be inspected by identifier after it is not relied on as a visible recent row ## Failure Conditions - Pause still freezes the only available evidence for a selected quote. - A selected quote cannot be found once it leaves the rolling recent table. - The lookup path searches only the browser's current rows instead of durable history. - The UI improves labels but still cannot answer what happened after `Awaiting executor`. - Missed-quote filters hide the selected investigation or make old rows unreadable. - The implementation changes trading behavior or strategy economics. - No regression test covers the row-follow-up bug. ## Real Versus Fake - Real in scope: dashboard investigation backed by durable quote, decision, command, executor result, and outcome rows already stored by repo-owned services. - Still fake or incomplete: venue-native final fill truth, fee-aware realized PnL, broader quote analytics workbench, and historical aggregate drilldowns beyond the existing retained lifecycle detail and rollups.