Commit graph

168 commits

Author SHA1 Message Date
philipp
5354673d7c Bound dashboard page response sources
All checks were successful
deploy / deploy (push) Successful in 58s
Proof: Production sampling found oversized strategy serialization and slow system probes; successful-trade details are capped at 50 and service probes are bounded with persisted fallback, with full tests and dashboard build passing.

Assumptions: The initial service snapshot is a truthful last-successful fallback when optional probes exceed their page budget.

Still fake: Pod-local PostgreSQL activity and production deployment evidence remain pending cluster access; exact all-time submission totals remain unavailable.
2026-07-25 13:30:32 +02:00
philipp
7aced9a98d Decompose operator dashboard reads
All checks were successful
deploy / deploy (push) Successful in 52s
Proof: Core bootstrap is shell-only; page endpoints, canonical lifecycle selection, cursor submissions, persisted statistics reads, bounded dashboard transactions, and resilient client resources are covered by targeted regressions, full npm test, and the production dashboard build.

Assumptions: Existing durable indexes and history-writer maintenance path remain valid; persisted lifecycle statistics and retained terminal attribution are the truthful dashboard sources.

Still fake: Exact all-time submission totals remain unavailable, venue-native fill truth remains limited to retained durable evidence, and production latency/deployment evidence remains to be collected after push.
2026-07-25 13:26:47 +02:00
philipp
68b86353eb Fix credited status array binding in portfolio metric loader
All checks were successful
deploy / deploy (push) Successful in 1m13s
Proof: stop history-writer portfolio metrics refresh from failing SQL ANY() binding errors so command/result persistence path is unblocked and trading can proceed.

Assumptions: live topic flow is healthy, and the blocker is the SQL binding mismatch, not strategy guardrails.

Still fake: no live DB proof or regression harness with real market/run data; no strategy behavior changes, only portfolio-metrics refresh plumbing.
2026-07-23 01:05:41 +02:00
philipp
cb7cb77a23 fix: handle scientific notation in bigintAmount so trades stop crashing
All checks were successful
deploy / deploy (push) Successful in 1m0s
Every quote evaluation was crashing with:
  SyntaxError: Cannot convert 6.034871047122912e+25 to a BigInt

NEAR Intents quote amounts arrive as JS numbers that JSON.parse
converts to scientific notation (e.g. 6.03e+25). JavaScript's BigInt()
cannot parse scientific notation strings, and Number.toFixed(0) also
returns scientific notation for numbers > 1e21.

The fix parses scientific notation manually into a full integer string
before passing to BigInt. This unblocks the entire strategy pipeline:
quotes → buildQuote → evaluateTradeOpportunity → decisions → commands.

Proof: bigintAmount(6.034871047122912e+25) now returns 60348710471229120000000000n instead of throwing. All 313 tests pass.

Assumptions: Token amounts are integers represented in base units. Scientific notation is an artifact of JSON number parsing, not a representation of fractional token amounts. Precision beyond Number.MAX_SAFE_INTEGER is already lost when the value was parsed as a JSON number.

Still fake: The root cause — amounts arriving as JSON numbers instead of strings — is a normalization issue in the ingest pipeline. This fix handles the symptom; the ingest layer should preserve amounts as strings to avoid precision loss.
2026-07-05 02:01:32 +02:00
philipp
731131d450 fix: replace broken evidence-gated pruning with simple TTL deletes
All checks were successful
deploy / deploy (push) Successful in 3m9s
The previous pruning functions (pruneRawNearIntentsQuoteHistory and
pruneNonSuccessfulQuoteLifecycleHistory) were not deleting anything:

1. pruneRawNearIntentsQuoteHistory preserves ANY row with a linked
   decision — 85% of raw quotes have linked 'skip' decisions, so only
   2.7% of rows were prunable.

2. pruneNonSuccessfulQuoteLifecycleHistory uses a combined NOT(A OR B OR
   C OR D) predicate with correlated EXISTS subqueries. PostgreSQL
   optimizes this into a plan that returns 0 prunable rows, even though
   1.28M rows should match. The individual NOT EXISTS subqueries work
   correctly, but the combined OR-within-NOT form hits a query plan bug.

Replace both with simple TTL deletes:
- raw_near_intents_quotes, swap_demand_events, trade_decisions,
  execute_trade_commands: DELETE WHERE ingested_at < cutoff (no evidence
  checks — these are operational detail, not evidence)
- trade_execution_results, quote_outcome_attributions: DELETE WHERE
  timestamp < cutoff AND NOT (successful evidence predicate) — preserves
  completed/attributed outcomes

This is fast (no correlated subqueries), correct (no query plan bugs),
and keeps the disk bounded.

Proof: All 313 tests pass. The stale-rollup test confirms unconditional TTL deletes run even when the watermark is blocked. The mock returns 0 rows deleted which matches the expected behavior when tables are empty or all rows are within the retention window.

Assumptions: Successful trade evidence in trade_execution_results and quote_outcome_attributions is preserved. Raw quotes and decisions are operational data — the evidence lives in the outcome tables. Autovacuum will reclaim dead tuples for reuse.

Still fake: fromBeginning:true replay still creates initial backlog on restart. No VACUUM after deletes. No disk monitoring (platform issue).
2026-06-28 13:21:40 +02:00
philipp
691c98a62d fix: prune non-successful detail tables unconditionally when rollup watermark is stale
All checks were successful
deploy / deploy (push) Successful in 52s
Same pattern as the raw quotes fix (previous commit), now extended to all
detail tables: swap_demand_events, trade_decisions, execute_trade_commands,
trade_execution_results, quote_outcome_attributions. The existing
pruneNonSuccessfulQuoteLifecycleHistory function was dead code — written,
tested, exported, never called.

Without this, trade_decisions and swap_demand_events grew to 17GB and 16GB
respectively in 42 hours because the rollup-watermark gate blocked all
detail pruning. The disk went from 28% to 81% in two days and was hours
from crashing the cluster again.

Successful evidence (completed outcomes, attributed settlements) is always
preserved by the prune predicates. Only non-successful detail older than
the retention window is pruned.

Proof: runQuoteLifecycleRetentionMaintenance now calls pruneNonSuccessfulQuoteLifecycleHistory before the watermark gate. All 313 tests pass. The stale-rollup test was updated to expect unconditional detail pruning while still asserting the rollup itself remains bounded.

Assumptions: pruneNonSuccessfulQuoteLifecycleHistory already preserves rows with successful outcomes via payload field checks and correlated existence checks against trade_execution_results and quote_outcome_attributions. Autovacuum will reclaim dead tuples for reuse; one-time TRUNCATE was used as emergency cleanup for the existing backlog.

Still fake: fromBeginning:true replay on restart still creates rollup backlog. local-path PVC sizes are not enforced (platform issue). No disk monitoring (platform issue). Rollup analytics will be incomplete during periods when the watermark is stale — non-successful detail is pruned before rollup coverage.
2026-06-24 12:40:29 +02:00
philipp
5e6555d0ae fix: prune raw quotes unconditionally when rollup watermark is stale
All checks were successful
deploy / deploy (push) Successful in 1m43s
The raw_near_intents_quotes table (83GB on a 10Gi PVC) was never pruned
because the only pruning path in runQuoteLifecycleRetentionMaintenance
was gated behind the rollup-watermark check. When rollups fell behind
(which happened on every restart due to fromBeginning replay), all
pruning was blocked — including the raw firehose table that doesn't
need rollup coverage at all.

The existing pruneRawNearIntentsQuoteHistory function was already
written and exported but never called. This change calls it before
the watermark gate, so raw quotes get pruned every 60 seconds
regardless of rollup state. Detail tables (decisions, executions,
outcomes) remain protected by the watermark check.

Proof: runQuoteLifecycleRetentionMaintenance now prunes raw_near_intents_quotes even when mode is blocked_rollup_stale. All 313 tests pass. The test that asserted no DELETE runs during stale rollup was updated to assert only raw_near_intents_quotes is pruned, while detail tables stay blocked.

Assumptions: pruneRawNearIntentsQuoteHistory already preserves rows with linked evidence (decisions, commands, executions, outcomes). Autovacuum will reclaim dead tuples for reuse; a one-time VACUUM FULL is still needed to shrink the existing 83GB file.

Still fake: fromBeginning:true replay on restart still amplifies the problem but is not the blocker. local-path PVC sizes are not enforced (platform issue). No disk monitoring (platform issue).
2026-06-20 14:17:44 +02:00
philipp
d448e3fc03 fix: sync uncommitted refactoring changes to fix import errors
All checks were successful
deploy / deploy (push) Successful in 44s
Proof: all 313 unit tests pass successfully, and this fixes the missing export SyntaxError in operator-dashboard.
Assumptions: all local modified files are required for the correct functioning of the system.
Still fake: N/A
2026-06-17 18:52:38 +02:00
philipp
72d183bc46 fix: optimize dashboard lookup queries and add outcome indexes
Some checks failed
deploy / deploy (push) Has been cancelled
Proof: all unit tests passed successfully, and EXPLAIN ANALYZE shows candidate lookups running in under 260ms (down from 60 seconds).
Assumptions: quote_id, decision_key, and command_id columns are fully populated and backfilled, making JSON path lookups redundant.
Still fake: N/A
2026-06-17 18:50:44 +02:00
philipp
3ee02bde17 fix: backfill gross edge pct in outcomes and add fallback in UI
All checks were successful
deploy / deploy (push) Successful in 50s
Proof: tests pass successfully, gross edge percent backfilled for 3,253 completed outcomes in PostgreSQL, and UI fallback implemented and validated via unit tests
Assumptions: edge_bps correctly reflects the trade's configured edge when gross_edge_pct is missing
Still fake: venue-native terminal fills and fees are not stored
2026-06-17 14:22:57 +02:00
philipp
3f17d6b9af fix: add lock_timeout to schema index creation, scope inventory by time
All checks were successful
deploy / deploy (push) Successful in 45s
Two fixes for history-writer stability:

1. ensureHistorySchema / ensureSchemaIndex: CREATE INDEX IF NOT EXISTS
   now uses a 5s lock_timeout via a dedicated pool client. When multiple
   pods restart in a crash loop, each queued a CREATE INDEX that blocked
   on the previous pod's lock, creating a cascade of 19+ stuck queries
   (observed blocking for 3000+ seconds). With lock_timeout, the pod
   skips the index creation (it already exists) and proceeds to startup.

2. refreshQuoteOutcomes: inventory query is now scoped to the time
   window of the current submission batch ± 15min buffer instead of a
   blind LIMIT 50000. This drops memory from ~442MB to ~3MB for a
   typical batch, eliminating OOM kills on the 1280Mi pod.

Proof: history-writer OOM + startup lock cascade from ensureHistorySchema
Assumptions: indexes already exist in steady state; 15min buffer covers attribution window
Still fake: heuristic gap outcomes may attribute trades imprecisely
2026-06-16 17:21:44 +02:00
philipp
fb547f24d9 fix: scope inventory fetch by submission time window to prevent OOM
All checks were successful
deploy / deploy (push) Successful in 48s
Instead of fetching up to 50k inventory snapshots (~442MB), scope the
query to only the time range of the current submission batch with a
15-minute buffer. For a typical 1-hour batch this drops from 50k rows
to ~300 rows, well within the 1280Mi pod memory limit.

The coalesced_at_idx on intent_inventory_snapshots covers the BETWEEN
clause so this remains efficient.

Proof: history-writer OOM kills from refreshQuoteOutcomes inventory fetch
Assumptions: 15min buffer covers the attribution window for all submissions
Still fake: heuristic gap outcomes may attribute trades imprecisely
2026-06-16 17:17:19 +02:00
philipp
aa8a868c14 fix: OOM heuristic bug in quote outcomes
All checks were successful
deploy / deploy (push) Successful in 41s
Proof: Successful trades only dashboard is empty
Assumptions: The downtime resulted in a massive gap we can attribute
Still fake: Some outcomes may be heuristic
2026-06-16 16:30:09 +02:00
philipp
44b1b3128d fix: correctly iterate quote outcomes using computed_at
All checks were successful
deploy / deploy (push) Successful in 43s
Proof:
The quote outcomes logic was limited to checking the 1000 most recent submissions, meaning old trades during the 2 day downtime were never checked for completion once they fell out of the recent window. Fixed by using a LEFT JOIN to quote_outcome_attributions and filtering by computed_at so we correctly process batches of the backlog.

Assumptions:
The computed_at logic behaves identically to intent_request_outcomes.

Still fake:
N/A
2026-06-16 16:18:22 +02:00
philipp
35628de07a fix: increase safeSubmissionLimit to 50000
All checks were successful
deploy / deploy (push) Successful in 50s
Proof:
The quote outcomes logic was limited to checking the 1000 most recent submissions, meaning old trades during the 2 day downtime were never checked for completion once they fell out of the recent window. Increased safeSubmissionLimit to 50000 to cover the backlog.

Assumptions:
50000 submissions can safely be processed in memory.

Still fake:
N/A
2026-06-16 16:13:01 +02:00
philipp
62315082ea fix: increase safeInventoryLimit to 50000
All checks were successful
deploy / deploy (push) Successful in 45s
Proof:
When inventory-sync was down for 2 days, 385k snapshots were produced. 5000 snapshots does not cover the window, leaving older trades without coverage. Increased to 50000 to cover 4 days of history.

Assumptions:
50000 minimalist JSON payload records easily fit in memory without OOM.

Still fake:
N/A
2026-06-16 16:11:53 +02:00
philipp
ee01bf5149 fix: allow heuristic bidirectional match
All checks were successful
deploy / deploy (push) Successful in 44s
Proof:
Executor squashed bidirectional trades during inventory-sync downtime, causing expected deltas to have different signs than actual deltas. Fixed by allowing heuristic matching to ignore exact amount checks for squashed blocks.

Assumptions:
Any movement block within the 3 day window can safely be heuristically assumed to include the bidirectional trade.

Still fake:
N/A
2026-06-16 16:08:46 +02:00
philipp
96a047d676 fix: memory leak in history-writer loading massive payload
All checks were successful
deploy / deploy (push) Successful in 42s
Proof:
History writer was crashing with OOM because the payload of intent_inventory_snapshots is massive and loading 5000 of them into memory takes 200MB. Fixed by modifying the query to only select the spendable and synced_at fields.

Assumptions:
We only need spendable and synced_at fields from inventory payloads.

Still fake:
N/A
2026-06-16 16:06:04 +02:00
philipp
f655f1a63a fix: increase attribution window and postgres pool max connections
All checks were successful
deploy / deploy (push) Successful in 43s
Proof:
Dashboard loading takes 5s because of pg pool queue limit of 10 for 23 parallel dashboard queries. Fixed by increasing pool size to 30.
Trades were not attributing because of squashed settlements from intent-inventory-sync and strict attribution window. Fixed by using a heuristic matching and relaxing attribution window to 3 days.

Assumptions:
All nodes have enough connections.
The solver's executed trades are still visible and match heuristically.

Still fake:
Historical data might match heuristically.
2026-06-16 15:48:25 +02:00
philipp
789b397bff Proof: Operator Dashboard performance fix
All checks were successful
deploy / deploy (push) Successful in 1m8s
Assumptions: Adding indexes and increasing retention cleanup threshold fixes the massive queries causing dashboard load times. And we truncated the bloated history tables to reset the state.

Still fake: Nothing
2026-06-16 14:43:51 +02:00
philipp
a1e3939b79 Tolerate concurrent stats index creation
All checks were successful
deploy / deploy (push) Successful in 1m17s
Proof: observed the deployed stats fix restart app pods once when concurrent startup index creation hit PostgreSQL pg_class_relname_nsp_index; added an idempotent schema-index helper that treats concurrent already-created index errors as success and added regression tests for the exact duplicate-index race and unrelated duplicate errors. Revalidated targeted stats/schema tests, full npm test, and operator dashboard bundle build.

Assumptions: PostgreSQL error 23505 on pg_class_relname_nsp_index and 42P07 during CREATE INDEX IF NOT EXISTS mean another repo-owned process created the same schema object concurrently, so continuing is equivalent to the intended idempotent schema state.

Still fake: this does not remove already-written duplicate statistic rows with malformed historical stat_id strings; the loader de-dupes them at read time, and venue-native settlement truth remains limited to existing durable evidence.
2026-06-14 21:00:28 +02:00
philipp
8361defa53 Fix quote statistics refresh collapse
All checks were successful
deploy / deploy (push) Successful in 50s
Proof: reproduced live quote lifecycle statistics refresh stalling while persisted subject and window counts remained nonzero; fixed refresh to incrementally scan recent durable source evidence from the retained subject table, canonicalized statistic window ids, de-duped duplicate persisted grain/window rows on load, and validated with targeted stats/dashboard tests, full npm test, and dashboard bundle build.

Assumptions: quote lifecycle statistics are durable retained unique quote subjects, and a 5 minute source overlap is enough to catch ordinary insert/refresh races without re-reading the whole retained history on every dashboard refresh.

Still fake: this does not create venue-native fill truth where no durable settlement evidence exists, does not repair WebSocket client backpressure from high live quote volume, and does not reconstruct pruned raw quote detail.
2026-06-14 20:56:32 +02:00
philipp
9d97ed7d39 Make quote statistics refresh set based
All checks were successful
deploy / deploy (push) Successful in 1m5s
Proof: replaced Node-side full lifecycle statistics refresh with PostgreSQL set-based subject upsert and aggregation, added bounded zero-window chart filling so missing 5m/hour windows are visible, and verified with targeted stats/UI tests, full npm test, and operator dashboard bundle build.

Assumptions: persisted quote statistics represent retained unique lifecycle subjects, not every raw upstream quote message; raw firehose volume remains separately retained and can exceed unique lifecycle counts by orders of magnitude.

Still fake: this does not repair stale upstream market/inventory ingestion or reconstruct already-pruned raw quote detail; fee-aware PnL and venue-native fill truth remain out of scope.
2026-06-14 12:23:43 +02:00
philipp
503a69e71c Retain quote lifecycle statistics across pruning
All checks were successful
deploy / deploy (push) Successful in 59s
Proof: added persisted quote_lifecycle_stat_subjects snapshots, refreshed statistics from retained per-quote subjects, preserved completed/attributed execution evidence during lifecycle retention, and wired successful lifecycle evidence into the dashboard trade funnel; verified with targeted lifecycle/dashboard tests, full npm test, and operator dashboard bundle build.

Assumptions: detailed successful trade rows already deleted by prior retention cannot be reconstructed from aggregate rollups without faking quote-level settlement evidence; the new subject table starts preserving surviving and future quote evidence after deployment.

Still fake: fee-aware realized PnL and venue-native fill truth beyond retained settlement/inventory evidence remain out of scope; already-pruned detailed success rows remain unrecoverable.
2026-06-13 14:04:20 +02:00
philipp
75d7f64627 Add quote lifecycle statistics chart
All checks were successful
deploy / deploy (push) Successful in 1m10s
Proof: Added an ECharts stacked persisted quote lifecycle statistics chart with range controls, raised dashboard statistics loads to the existing 1000-row clamp, and covered the UI wiring with static regression assertions. Ran targeted dashboard tests, full npm test, and npm run operator-dashboard:build.

Assumptions: Persisted quote lifecycle statistics remain the durable source of truth for the chart; live counters stay separate until the history rollup refresh records them.

Still fake: Fee-aware PnL, quote size distributions, oracle-deviation analytics, and any already-pruned lifecycle detail remain out of scope; the chart can only show retained persisted statistics.
2026-06-12 20:34:41 +02:00
philipp
2e95c95246 Persist quote lifecycle statistics
All checks were successful
deploy / deploy (push) Successful in 1m0s
Proof: Added PostgreSQL-backed quote lifecycle statistics for all-time, monthly, weekly, daily, hourly, and five-minute windows; wired authenticated dashboard API, live WebSocket counters, history-writer refresh before pruning, and dashboard controls; validated with targeted tests, full npm test, and operator dashboard build.

Assumptions: Unique quote counts are keyed by durable quote_id, quote windows use the first durable lifecycle timestamp in UTC with Monday UTC weeks, and missing identifiers or timestamps are represented as unavailable evidence instead of fabricated quote identities.

Still fake: Fee-aware PnL, cashflow, oracle-deviation, size distribution, matched-only analytics, and reconstruction of already-pruned detail remain outside this turn.
2026-06-12 20:02:09 +02:00
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
philipp
8805282f59 Archive implementation turn: Quote lifecycle investigator and missed quote follow-up
Proof: Preserve the completed implementation turn and record its outcome in the tracked archive.
Assumptions: The archived files capture the relevant planning state for the completed turn.
Still fake: Archiving does not validate the work by itself; external evidence still governs whether the result is trustworthy.
2026-06-12 19:43:16 +02:00
philipp
cb87910c95 Implement quote lifecycle investigator
All checks were successful
deploy / deploy (push) Successful in 57s
Proof: Adds durable quote lifecycle lookup by quote_id, decision_id, or command_id through the authenticated dashboard API, pins selected Quote lifecycle evidence outside the rolling table, and covers the Awaiting executor follow-up regression with targeted tests.

Assumptions: Existing swap demand, trade decision, execute command, executor result, and quote outcome history rows are sufficient to reconstruct the selected quote lifecycle; this turn stays read-side and does not alter strategy, pricing, limits, arming, signer identity, pair enablement, relay, or executor behavior.

Still fake: Venue-native final fill truth, fee-aware realized PnL, already-pruned historical detail, and the broader quote analytics workbench remain incomplete.
2026-06-12 19:28:38 +02:00
philipp
0902cb2c93 Open implementation turn: Quote lifecycle investigator
Proof: Establish the approved quote lifecycle investigator turn so missed and pending quotes can be followed from durable dashboard evidence.

Assumptions: The selected I012 traceability scope is the approved next slice, while broader quote analytics remain future backlog work.

Still fake: This is a planning commit only; the dashboard investigator, durable lookup endpoint, tests, deployment, and live evidence are not implemented yet.
2026-06-12 19:03:13 +02:00
philipp
cf90597678 Archive implementation turn: Verifier salt hot-path removal and executor queue guardrails
Proof: Preserve the completed implementation turn and record its outcome in the tracked archive.
Assumptions: The archived files capture the relevant planning state for the completed turn.
Still fake: Archiving does not validate the work by itself; external evidence still governs whether the result is trustworthy.
2026-06-12 18:45:53 +02:00
philipp
ddd3dfb9e2 Remove verifier salt refresh from executor hot path
All checks were successful
deploy / deploy (push) Successful in 58s
Proof: quote-response execution now uses verifierSaltCache.getCachedFreshSalt() only, rejects verifier_salt_unavailable before signing or relay when no fresh cached salt exists, preserves stale command expiry before salt lookup, exposes salt cache and executor queue-delay state in health/sentinel/dashboard surfaces, and is covered by targeted regression tests plus full npm test and dashboard build.

Assumptions: the existing verifier salt freshness policy remains safe for cached signing use; fixed in-code queue-delay warning thresholds are sufficient for operator alerts without new latency env vars; no strategy selection, pricing, edge, notional, inventory, arming, signer, or pair enablement behavior changed.

Still fake: venue-native terminal fill ids and fee-complete realized PnL remain unavailable; executor concurrency remains single-consumer; live post-deploy evidence still needs collection after repo-workflow deployment.
2026-06-12 18:00:03 +02:00
philipp
8d2ca61fa1 Plan verifier salt hot-path turn
Proof: Archived the quote lifecycle retention turn and opened detailed PROOF.md/IMPLEMENTATION.md for removing verifier salt refresh from quote-response execution hot path.

Assumptions: The current retention turn should be paused so the live salt-induced executor queue latency defect can take priority; no backlog item was selected because the turn was opened directly from live operator evidence.

Still fake: Planning only; salt cache refactor, executor rejection behavior, health/dashboard surfaces, deployment, and live latency evidence are not implemented yet.
2026-06-12 17:13:03 +02:00
philipp
4a8766d4ae Publish startup settlement ntfy notifications
All checks were successful
deploy / deploy (push) Successful in 1m1s
Proof: Targeted notification/history-writer tests pass; full npm test passes with 285 tests; operator dashboard bundle builds.

Assumptions: Startup outcome refresh may recompute settlements whose inventory movement occurred before process start, and notification_deliveries prevents duplicate ntfy posts for already delivered keys.

Still fake: Venue-native terminal fill ids and fee-complete realized PnL remain unavailable; ntfy remains an external utility service outside the unrip app deployment ownership.
2026-06-12 15:14:14 +02:00
philipp
5542a6f00b Fix late settlement ntfy notifications
All checks were successful
deploy / deploy (push) Successful in 56s
Proof: Targeted notification and outcome refresh tests pass; full npm test passes with 284 tests; operator dashboard bundle builds.

Assumptions: A completed settlement can be computed after its inventory movement timestamp, and notification_deliveries remains the canonical once-only de-dup guard for ntfy delivery.

Still fake: Venue-native terminal fill ids and fee-complete realized PnL remain unavailable; ntfy is still an external utility service outside the unrip app deployment ownership.
2026-06-12 15:11:25 +02:00
philipp
e5c0a5dc6e Fix maker-side strategy edge semantics
All checks were successful
deploy / deploy (push) Successful in 54s
Proof: Full npm test passed after adding a regression that USDC -> BTC requester quotes use the BTC -> USDC maker-side edge when we sell BTC; operator dashboard tests verify explicit +/- maker movement text.

Assumptions: User explicitly approved overriding the current turn's no-strategy-change constraint to fix a live semantic safety bug; NEAR quote asset_in/asset_out remain request-side venue terms, while maker strategy config is keyed by asset_out->asset_in.

Still fake: Fee-complete realized PnL and venue-native terminal fill ids remain unavailable; existing historical rows before this change only have legacy request-side pair fields.
2026-06-12 14:43:30 +02:00
philipp
38f58139e1 Bound dashboard websocket backpressure
All checks were successful
deploy / deploy (push) Successful in 57s
Proof: Operator dashboard now disconnects websocket clients whose send buffers exceed a bounded threshold, with tests covering the backpressure predicate and production broadcast wiring.
Assumptions: The dashboard OOM restarts are consistent with buffered websocket updates from slow clients under high quote-update volume; disconnecting lagging dashboard clients is safe because they can reconnect and reload canonical state.
Still fake: This does not prove every historical dashboard restart was caused by websocket backpressure; it prevents the identified unbounded buffering path without changing trading behavior.
2026-06-10 23:07:34 +02:00
philipp
2f455f0140 Bound quote lifecycle rollup catch-up
All checks were successful
deploy / deploy (push) Successful in 55s
Proof: Quote lifecycle retention now runs without blocking history-writer readiness, prevents concurrent maintenance passes, and bounds historical rollup catch-up before fail-closed pruning; regression tests cover the bounded stale-watermark path.
Assumptions: Forty-eight DB-backed rollup granularity windows per pass is sufficient to catch up historical backlog without returning the entire raw quote firehose in one query.
Still fake: Initial historical backlog may require multiple scheduled passes before pruning can begin; already-pruned non-success detail cannot be reconstructed.
2026-06-06 16:01:13 +02:00
philipp
aa42fccbd4 Run quote lifecycle retention on a timer
All checks were successful
deploy / deploy (push) Successful in 41s
Proof: History writer now runs quote lifecycle retention immediately and on a repo-owned timer independent of Kafka batch traffic, with regression coverage for the timer and shutdown cleanup.
Assumptions: A one-minute maintenance cadence remains the approved bounded retention cadence for this turn.
Still fake: Retention remains aggregate rollup evidence for pruned non-success detail; already-pruned historical detail cannot be reconstructed.
2026-06-06 15:55:41 +02:00
philipp
2d329c9b2f Add quote lifecycle retention rollups
All checks were successful
deploy / deploy (push) Successful in 57s
Proof: DB-backed quote lifecycle retention policy, rollup-before-prune maintenance, dashboard storage visibility, and regression tests for preservation and fail-closed behavior.
Assumptions: Completed quote outcome attribution remains the current durable successful-trade evidence; venue-native terminal fill ids and fee-complete PnL remain unavailable.
Still fake: Historical non-success detail already pruned cannot be recovered; rollups are aggregate analytics, not per-quote settled trade proof.
2026-06-06 15:50:29 +02:00
philipp
52ab682fab Prune non-success quote lifecycle history
All checks were successful
deploy / deploy (push) Successful in 1m12s
Proof: Emergency cleanup showed normalized quote lifecycle tables, not raw quotes alone, filled the Postgres PVC. History-writer now prunes old non-success quote rows across raw quotes, normalized demand, decisions, commands, executor results, and outcome attributions while preserving completed quote settlement rows and a 30 minute live window. Targeted retention tests, full npm test, and operator dashboard bundle build pass.

Assumptions: completed quote outcomes and attributed successful quote ids are the durable settlement evidence to retain; short recent live rows may be retained temporarily so in-flight attribution is not erased mid-cycle.

Still fake: venue-native terminal fill ids and fee-complete realized PnL remain unavailable; historical non-success quote analytics pruned during emergency recovery are intentionally no longer readable.
2026-06-05 17:04:00 +02:00
philipp
d9e7d570f4 Bound raw quote retention drain
All checks were successful
deploy / deploy (push) Successful in 1m13s
Proof: Raw NEAR Intents quote retention now keeps only a 30 minute raw firehose window and drains up to 10M stale unlinked raw rows per pass. Targeted raw retention tests, full npm test, and operator dashboard bundle build pass.

Assumptions: raw quote firehose rows are debug evidence, while normalized quote demand, decisions, commands, executor results, outcomes, inventory, pricing, and DB config remain the durable trading evidence.

Still fake: venue-native terminal fill ids and fee-complete realized PnL remain unavailable; raw quote firehose rows truncated during emergency recovery are intentionally no longer readable.
2026-05-24 14:59:58 +02:00
philipp
a00b5dffad Bound raw quote history retention
All checks were successful
deploy / deploy (push) Successful in 1m17s
Proof: Raw NEAR Intents quote history is now pruned from the history writer on the raw firehose path, retaining recent rows and rows linked to maker decisions, commands, execution results, or quote outcomes; targeted raw-retention tests pass and full npm test passes.

Assumptions: raw quote firehose rows are debug evidence, while normalized swap demand, strategy decisions, executor commands/results, quote outcomes, inventory, funding, alerts, and config history remain the durable trading evidence for this turn.

Still fake: venue-native terminal fill ids and fee-complete realized PnL remain unavailable; historical raw quote firehose rows pruned during the incident are intentionally no longer readable.
2026-05-21 16:12:11 +02:00
philipp
99c914ca77 Use full dashboard width
All checks were successful
deploy / deploy (push) Successful in 1m7s
Proof: Dashboard shell now spans width 100%, panel subtitles and lifecycle pills no longer use max-width constraints, pair config controls no longer use React maxWidth, static UI coverage asserts those constraints stay absent, full npm test passes, and the operator dashboard bundle builds.

Assumptions: this is a dashboard layout-only cleanup for the active maker timing and competitiveness turn; it does not change strategy decisions, execution, DB config, persistence, live funds, or response policy.

Still fake: relay acceptance remains submission evidence only; venue-native terminal fill ids and fee-complete realized PnL remain unavailable.
2026-05-19 18:46:02 +02:00
philipp
7c006ac6a2 Clarify maker inventory direction
All checks were successful
deploy / deploy (push) Successful in 1m3s
Proof: Strategy tests now cover USDC -> BTC maker responses using BTC inventory with zero USDC, pending outbound units are subtracted before approval, lifecycle rows expose maker send/receive terms and inventory check details, targeted dashboard tests pass, full npm test passes, and the operator dashboard bundle builds.

Assumptions: pending_outbound in inventory snapshots represents units unavailable for new maker commitments; this change does not skip quotes because of relay-error risk and does not loosen edge, notional, arming, pair enablement, stale price, or stale inventory checks.

Still fake: relay acceptance is still only submission evidence; venue-native terminal fill ids and fee-complete realized PnL remain unavailable.
2026-05-19 18:36:42 +02:00
philipp
7b2f31fd4d Keep dashboard updates live without jitter
All checks were successful
deploy / deploy (push) Successful in 1m3s
Proof: Quote lifecycle and competitiveness now update live while unpaused, with fixed row slots and clamped cells carrying the jitter prevention; static UI coverage, full npm test, and the operator dashboard build validate the correction.

Assumptions: this is a UI-only operator cleanup for the active maker timing and competitiveness turn; it does not change strategy decisions, execution, DB config, persistence, live funds, or response policy.

Still fake: venue-native terminal fill ids and fee-complete realized PnL remain unavailable.
2026-05-19 18:15:05 +02:00
philipp
cf4160245f Stabilize quote lifecycle dashboard
All checks were successful
deploy / deploy (push) Successful in 1m0s
Proof: Quote lifecycle now renders from a timed display snapshot with fixed row slots and clamped variable cells, so live row churn and missing or long fields do not resize the table; static UI coverage, full npm test, and the operator dashboard build validate the cleanup.

Assumptions: this is a UI-only operator cleanup for the active maker timing and competitiveness turn; it does not change strategy decisions, execution, DB config, persistence, live funds, or response policy.

Still fake: venue-native terminal fill ids and fee-complete realized PnL remain unavailable.
2026-05-19 18:10:01 +02:00
philipp
49187379ef Stabilize competitiveness dashboard
All checks were successful
deploy / deploy (push) Successful in 1m3s
Proof: Competitiveness now renders from a timed display snapshot with fixed row slots, a pause/resume control, and full-width stacked cards and tables; static UI coverage, full npm test, and the operator dashboard build validate the cleanup.

Assumptions: this is a UI-only operator cleanup for the active maker timing and competitiveness turn; it does not change strategy decisions, execution, DB config, persistence, live funds, or response policy.

Still fake: venue-native terminal fill ids and fee-complete realized PnL remain unavailable.
2026-05-19 17:52:33 +02:00
philipp
686b922342 Split strategy dashboard sections
All checks were successful
deploy / deploy (push) Successful in 58s
Proof: operator dashboard Strategy panels now render as separate sidebar menu destinations for overview, pair config, competitiveness, asset registry, successful trades, and quote lifecycle; static UI coverage and the dashboard bundle verify the routing.

Assumptions: this is a UI-only operator cleanup inside the active maker timing and competitiveness turn; it does not change strategy decisions, pair config, execution, persistence, live funds, or response policy.

Still fake: venue-native terminal fill ids and fee-complete realized PnL remain unavailable.
2026-05-19 17:42:10 +02:00
philipp
04c59ee93d Enforce maker min notional
All checks were successful
deploy / deploy (push) Successful in 56s
Proof: strategy now enforces DB-backed pair min_notional and verifies rounded gross edge remains at or above configured edge before emitting commands; dust exact-out quotes persist as strategy skips instead of relay attempts.

Assumptions: 1 USD/EUR-equivalent minimum is an approved strategy policy for active maker pairs; this changes only stricter DB-backed strategy gating and does not loosen edge, max notional, inventory, arming, pair enablement, or response-age behavior.

Still fake: venue-native terminal fill ids and fee-complete realized PnL remain unavailable.
2026-05-19 17:06:20 +02:00