unrip/PROOF.md
philipp 893617c30d Open implementation turn: Persisted quote statistics
Proof: Establish the approved persisted quote statistics turn with falsifiable rollup, API, dashboard, and validation requirements.

Assumptions: The requested statistics are the active implementation scope, and broader analytics from the old backlog item remains follow-up work.

Still fake: Planning docs only; no persisted statistics, API, dashboard, tests, deployment, or live evidence are implemented by this commit.
2026-06-12 19:45:24 +02:00

74 lines
5.2 KiB
Markdown

# Implementation Proof: Persisted quote statistics rollups and live counters
Status: open
Opened: 2026-06-12
## Hypothesis
Persisted quote lifecycle statistics over 5-minute, hourly, daily, weekly, monthly, and all-time windows will let the operator answer "how many quotes did we see and where did they end up?" without relying on the rolling dashboard table or browser memory.
## Scope
- This turn implements the persisted quote-state rollup part of the selected analytics backlog item. The broader analytics workbench work, including quote volume distribution, size buckets, oracle-deviation views, matched-only filters, and broader execution analytics, remains backlog follow-up scope.
- Use the existing durable quote lifecycle/history data and existing PostgreSQL storage. Do not add a new storage system, retention policy, or long-running external job outside the repo-owned workflow.
- Persist aggregates for these grains:
- `all_time`
- `month`
- `week`
- `day`
- `hour`
- `five_minute`
- A quote is assigned to a time-window by its first observed durable lifecycle timestamp in UTC. Weekly windows start on Monday UTC. The quote's state bucket may refresh later when new durable executor, relay, or settlement evidence arrives.
- Count unique quotes by `quote_id` when present. Rows without a durable quote identifier must remain visible as `unavailable` or `missing_identifier_count`; the implementation must not invent fake unique identifiers to inflate quote totals.
- Persist and expose at least these state buckets:
- `rejected_by_strategy`
- `awaiting_executor`
- `submission_failed`
- `submitted_no_reply`
- `success`
- `not_filled`
- `blocked_before_submit`
- `unavailable`
- Preserve old lifecycle and executor-result rows. Missing fields should count as unavailable instead of crashing or silently disappearing.
- Expose authenticated dashboard access to the persisted statistics and render them in the operator dashboard with live counts that continue updating independently of any paused recent lifecycle table.
## Non-goals
- Do not change strategy selection, pricing, edge thresholds, notional limits, inventory checks, arming, signer identity, pair enablement, executor behavior, relay behavior, or quote skipping behavior.
- Do not add active pair, edge, notional, latency, response-policy, or retention environment variables.
- Do not add PnL, fee-aware accounting, treasury cashflow, oracle-deviation analysis, size-bucket analytics, matched-only filters, or strategy tuning in this turn.
- Do not manually patch images, roll deployments, or repair the cluster outside the repo workflow.
- Do not rewrite `THESIS.md`.
## Definition of Done
- Existing quote lifecycle/history tables can be rolled up into persisted statistics for all requested grains and all-time totals.
- Aggregation is idempotent: recomputing the same history does not double-count quotes or duplicate windows.
- Each counted quote lands in exactly one state bucket per grain window, with terminal evidence taking precedence over intermediate states.
- The dashboard API returns authenticated persisted statistics, including all-time totals and recent windows.
- The dashboard UI shows the statistics, has controls for the requested grains, and live counts keep changing while the recent quote table is paused.
- Regression tests prove:
- unique quote dedupe across lifecycle, decision, command, executor, and relay evidence
- `submitted_no_reply` does not become `success` without durable success/settlement evidence
- a later executor or relay result refreshes the persisted bucket for the quote's original time window
- old or missing fields are represented as unavailable rather than throwing or hiding rows
- all requested window boundaries are UTC and weekly windows start Monday UTC
- all-time totals match the same classified quote set as the windowed stats
- Run targeted tests, full `npm test`, and build the dashboard bundle.
- Commit with `Proof:`, `Assumptions:`, and `Still fake:` in the commit body.
- Push and deploy only after tests pass, then collect live evidence for:
- new image from the repo workflow
- quote lifecycle live rows still flowing
- persisted statistics endpoint returning real rows
- live dashboard counts moving without relying on recent-table visibility
## Failure Conditions
- Statistics are derived only from browser state, recent WebSocket rows, or mock fixtures.
- A single quote can be counted more than once in the same grain window.
- Submitted-but-unanswered quotes are mislabeled as successful.
- Missing old fields crash aggregation or make rows vanish.
- The implementation changes trading behavior, execution behavior, pair enablement, thresholds, notional limits, inventory safety, or arming behavior.
- Deployment requires manual cluster image patching or ad hoc rollout intervention.
## What Is Real
- The proof is about durable aggregate truth from the same stored quote lifecycle evidence used by operator investigation and live lifecycle rows.
## Still Fake Or Out Of Scope
- Final venue-native fill truth remains limited to the durable evidence already present in the system.
- Fee-aware PnL, cashflow, benchmark markouts, quote size distributions, oracle-deviation analysis, and matched-only analytics remain future turns.