Proof: targeted executor and dashboard tests pass; npm test passes 239/239; operator dashboard bundle builds; git diff --check passes.
Assumptions: timing fields are observational only and do not change quote response policy, signing, concurrency, arming, or live funds behavior.
Still fake: venue-native terminal fill ids and fee-complete realized PnL remain unavailable.
Proof: npm test passes 238/238; operator-dashboard static UI test covers Relay response error_message and note rendering; operator-dashboard bundle builds successfully.
Assumptions: executor trade_result payloads already persist relay submission error.message and note fields for lifecycle rows, so this change only exposes stored evidence in the expanded dashboard detail.
Still fake: venue-native terminal fill ids and realized fee/PnL attribution remain unavailable.
Proof: npm test passes 238/238; operator-dashboard static UI test covers the rejected-by-strategy filter and pause/resume display controls; operator-dashboard bundle builds successfully.
Assumptions: pausing the quote lifecycle table should freeze only the rendered rows and relative-age display while socket state and runtime processing continue normally.
Still fake: venue-native terminal fill ids and realized fee/PnL attribution remain unavailable.
Proof: full npm test passes 238/238; deploy workflow static test and bootstrap script static test cover deletion of immutable redpanda-topic-bootstrap job before manifest apply.
Assumptions: redpanda-topic-bootstrap is idempotent and safe to recreate because it only ensures Kafka topics and retention settings.
Still fake: venue-native terminal fill ids and realized fee/PnL attribution remain unavailable.
Proof: targeted pair-native strategy, preflight, outcome, dashboard, and ops tests pass; full npm test passes 237/237; operator dashboard production bundle builds; ops watcher Python test passes.
Assumptions: DB asset, pair, strategy config, and price route rows remain canonical; legacy EURe fields stay only for old-row/API compatibility; local shell has no Kubernetes context for direct live namespace recheck.
Still fake: venue-native terminal fill ids and realized fee/PnL attribution remain unavailable; live deployment verification must happen through the repo workflow because manual cluster repair is out of scope.
Proof: Dashboard portfolio metrics now include DB-tracked USDC balances valued from live BTC/EUR and BTC/USDC reference prices, with regression coverage for the observed USDC inventory case.
Assumptions: USDC is cash-equivalent for valuation when a fresh BTC/USDC reference event is available; live trading safety remains governed by pair config and price route checks.
Still fake: Portfolio valuation still does not provide fee-complete realized PnL or generalized valuation for every imported non-stable asset.
Proof: node --test test/intent-requests.test.mjs verifies uncapped request preflights persist null slippage cap state.
Assumptions: request preflight payloads should expose both amount and slippage cap state so operator-visible records match DB strategy config.
Still fake: request settlement truth still depends on inventory-delta attribution instead of venue-native terminal fill events.
Proof: node --test test/operator-dashboard-app-static.test.mjs verifies dashboard controls forward nullable request limit fields.
Assumptions: operator-approved DB config updates may clear request_max_notional and request_max_slippage_bps by sending null through the dashboard control API.
Still fake: request settlement truth still depends on inventory-delta attribution instead of venue-native terminal fill events.
Proof: npm test (217/217), npm run operator-dashboard:build, and focused intent/trading-config tests cover DB-null request amount and slippage limits.
Assumptions: removing request amount and slippage caps is explicitly operator-approved for the current live-funds workflow; preflight remains side-effect-free and submit remains separate.
Still fake: request settlement truth still depends on inventory-delta attribution instead of venue-native terminal fill events.
Proof: npm test (215/215), npm run operator-dashboard:build, and focused intent/dashboard regressions cover bounded outcome refresh and dashboard bootstrap skipping synchronous refresh.
Assumptions: history-writer and executor remain responsible for durable intent outcome refresh; dashboard bootstrap should read persisted outcomes instead of recomputing them inline.
Still fake: dashboard quote outcomes still depend on inventory-delta attribution instead of venue-native terminal fill events.
Proof: npm test (212/212) and npm run operator-dashboard:build cover non-JSON auth failures and rebuilt the dashboard bundle.
Assumptions: browser auth failures may return plain text before a session cookie is established; API callers should receive JSON errors.
Still fake: dashboard quote outcomes still depend on inventory-delta attribution instead of venue-native terminal fill events.
Proof: npm test (209/209) covers stale command expiry, bounded executor state, bounded strategy quote cache, bounded quote outcome refresh, and resource guardrails.
Assumptions: current DB pair config and armed state remain the operator-approved live trading controls; stale quote commands are unsafe to submit after their min_deadline_ms.
Still fake: quote outcomes still infer fills from inventory deltas rather than a venue-native terminal fill event.
Proof: Live investigation showed doran-1 entered NodeNotReady with kubelet SystemOOM and TLS/control-plane timeouts while near-intents-ingest, history-writer, and operator-dashboard were the largest Node memory consumers. This commit adds websocket publish backpressure for the raw quote firehose and pod memory guardrails for the affected services.
Assumptions: Dropping quote frames while Kafka publishing is backpressured is safer than allowing unbounded in-flight publishes to take down the single-node cluster; retained Kafka/Postgres history remains best-effort under overload until the platform has enough capacity for full raw retention.
Still fake: This does not add durable queue spillover for skipped raw websocket frames, does not resize the node, and does not prove fee-complete trading PnL.
Proof: The rendered Kubernetes manifest now includes a Traefik TLS ingress for operator-dashboard and production basic auth, deploy workflow/bootstrap preserve the dashboard password as a secret, and static plus full node tests pass.
Assumptions: doran.133011.xyz is the intended public host because unrip.doran.133011.xyz and dashboard.doran.133011.xyz do not currently resolve.
Still fake: the public dashboard is not deployed or externally verified yet because the cluster host, Forgejo, and Kubernetes API timed out from this machine during this turn.
Proof: Ethereum 1Click assets now persist bridge chain eth:1, the current BTC/USDC seed uses eth:1, and regression tests cover Ethereum and Gnosis bridge-chain normalization.
Assumptions: NEAR Intents bridge RPC expects eth:1 for Ethereum deposit and recent-deposit endpoints.
Still fake: live ETH-USDC fills are not proven yet; runtime validation must confirm inventory refresh and quote lifecycle after deployment.
Proof: current BTC/USDC route seeding now targets the live Ethereum USDC wrapper; tests cover ETH-USDC route activation and prove Gnosis USDC no longer receives the automatic BTC/USDC route.
Assumptions: the live NEAR Intents quote stream is emitting nBTC with Ethereum USDC, and Ethereum USDC uses bridge chain eth.
Still fake: no live ETH-USDC solver fill is proven yet; Gnosis USDC may remain imported for visibility but is not intended as the active BTC/USDC trading wrapper.
Proof: Gnosis NEAR Intents assets now persist bridge chain eth:100, repo seed corrects legacy USDC chain rows, and tests prove USDC is not inventory-enabled until a pair activation enables it.
Assumptions: NEAR Intents bridge deposit_address uses eth:100 for Gnosis funding handles while dashboard blockchain labels remain gnosis.
Still fake: USDC deposit credit and live solver fills are not proven by this change; supported_tokens RPC remains upstream-unavailable.
Proof: supported_tokens bridge RPC failures no longer abort liquidity-manager deposit address refresh; regression tests cover the non-fatal warning path.
Assumptions: deposit handles remain chain-level NEAR Intents bridge data and Gnosis assets share the Gnosis handle when the bridge deposit_address RPC succeeds.
Still fake: USDC deposits are not proven credited yet; supported_tokens is still unavailable upstream until the bridge RPC responds successfully.
Proof: npm test passed 184/184; npm run operator-dashboard:build; focused route tests cover BTC/USDC route seeding, inventory tracking, Kraken/CoinGecko parsing, route-specific price selection, fresh BTC/USDC strategy approval, stale route blocking, and missing USDC reference fields.
Assumptions: BTC/USDC uses Kraken XBTUSDC as primary reference and CoinGecko bitcoin/USD as fallback with USDC ~= USD; operator-enabled maker pairs may mark their assets inventory-tracked, but imported assets remain non-trading by default.
Still fake: BTC/USDC taker request creation is not generalized; USDC/USD parity is an explicit assumption; solver liquidity and fee-complete PnL are not proven by this route.
Proof: npm test; node --check src/apps/inventory-sync.mjs; node --test test/inventory-sync-static.test.mjs test/trading-config.test.mjs.
Assumptions: Inventory refresh failures should be logged with the active pair when available, but error logging must not throw if trading config loading or refresh work fails.
Still fake: No BTC/USDC external reference price route or liquidity model exists; non-nBTC/EURe pairs still fail closed on missing price route until that path is built.
Proof: npm test; npm run operator-dashboard:build; focused regressions cover maker/taker activation creating config, invalid initial edge rejection, and invalid max-notional rejection.
Assumptions: Adding maker/taker/both mode should create an initial pair strategy config with operator-provided edge and max notional, but pairs without a real price route must remain blocked.
Still fake: No BTC/USDC external reference price route or liquidity model exists; non-nBTC/EURe pairs still fail closed on missing price route until that path is built.
Proof: npm test passed 174/174; npm run operator-dashboard:build passed; dashboard UI static test proves pair controls render before the long asset catalog table.
Assumptions: The add-pair interface was present but hidden below the 163-row asset registry, so moving it above the catalog makes the existing DB-backed control discoverable without changing trading semantics.
Still fake: no new price routes or liquidity discovery were added; non-current pairs without routes/config remain blocked from trading.
Proof: npm test passed 173/173; npm run operator-dashboard:build passed; regression tests cover omitting raw asset payloads from bootstrap rows and using an explicit 45s bootstrap timeout.
Assumptions: The timeout observed by the operator is the browser-side 15000ms fetch limit on /api/bootstrap; trimming asset rows and extending only the bootstrap timeout keeps the dashboard available while preserving visible asset and pair config.
Still fake: raw imported token payloads remain stored in Postgres but are not exposed through a per-asset dashboard detail view in this fix.
Proof: npm test passed 171/171; npm run operator-dashboard:build passed; regression tests cover pair activation/pause fail-closed behavior, per-pair edge controls, and asset deposit address exposure.
Assumptions: Activating a directed pair is operator-approved live-funds-adjacent control; trading still requires existing DB strategy config, price route, armed services, and inventory, so unsupported imported assets remain blocked.
Still fake: no new price routes or liquidity discovery were added; non-current pairs without routes/config remain visible but cannot trade.
Proof: npm test passed 166/166; npm run operator-dashboard:build passed; focused dashboard static tests cover removing the 20-row asset registry cap and requesting 250 catalog rows.
Assumptions: Current 1Click import has 163 supported tokens, so a 250-row dashboard catalog cap exposes the full current catalog while keeping the bootstrap bounded.
Still fake: no live funds movement; imported assets remain catalog-visible only unless explicitly inventory/trading enabled.
Proof: npm test passed 164/164; npm run operator-dashboard:build passed; focused dashboard API client and UI static tests cover timeout, empty HTTP 500, and retry/error loading state.
Assumptions: The current stuck dashboard is caused by a stale or unavailable local kubectl port-forward; the app should fail visibly and allow retry instead of waiting forever.
Still fake: no public dashboard ingress is part of this turn; local dashboard access still depends on Kubernetes API/port-forward availability.
Proof: npm test passed 161/161; npm run operator-dashboard:build passed; local dev dashboard API returned HTTP 200 after cleaning stale port-forward processes.
Assumptions: Forgejo main push remains the deployment path; imported 1Click assets should remain catalog-visible but not enter Funds balances unless inventory-enabled.
Still fake: no live funds movement; local dashboard access still depends on a healthy kubectl port-forward because no public dashboard ingress is part of this turn.
Proof: npm test passed 159/159; focused node --test for service-snapshot-summary and ops-sentinel static coverage passed; failed rollout showed ops-sentinel could not import src/core/service-snapshot-summary.mjs and this commit adds the module plus regression coverage.
Assumptions: Forgejo main push remains the deployment path; no manual kubectl reconciliation is needed because the failed rollout will be superseded by the repo workflow.
Still fake: no live funds movement; production rollout evidence still depends on the follow-up Forgejo deployment completing.
Proof: npm test passed 159/159; npm run operator-dashboard:build passed; repo-local Postgres importer smoke test imported 163 live 1Click tokens with only 3 inventory-enabled seed assets and nBTC/EURe pairs at 49 bps.
Assumptions: Forgejo main push is the repo deployment path; production has existing repo-managed POSTGRES_URL/POSTGRES_PASSWORD/NEAR_INTENTS_API_KEY secrets; startup seed may create initial current nBTC/EURe config but must preserve DB runtime pair flags after creation.
Still fake: no live funds movement was attempted; imported supported assets remain catalog-only unless explicitly enabled in DB; production rollout evidence still depends on the Forgejo deploy job completing after this push.
Proof: npm test; npm run operator-dashboard:build; live NEAR Intents status-page payload normalizes to operational for tracked BTC/Gnosis assets while 1Click still returns a EURe-to-nBTC dry quote.
Assumptions: Generic partial quoting or bridge-maintenance wording is not enough to pause our BTC/Gnosis path unless the incident names a core Intents component, protocol-wide swap outage, or our tracked chains/assets.
Still fake: Status-page relevance is still text/service scoped because the upstream status API does not expose a per-asset machine-readable impact matrix.
Proof: npm test; npm run operator-dashboard:build; live NEAR Intents status API normalized the current HOT destination-chain incident as operational for btc:mainnet and eth:100 tracked assets.
Assumptions: BSC, MONAD, XLAYER, PLASMA, POL, TON, OP, AVAX, STELLAR, and ADI incidents do not block our configured BTC/Gnosis NEAR Intents quote or executor paths unless the official incident also names core 1Click, solver, message bus, protocol-wide swaps, BTC, or Gnosis scope.
Still fake: Status relevance is text/service scoped to configured assets; it is not backed by a venue-provided per-asset machine-readable impact matrix.
Proof: npm test (147 passing); npm run operator-dashboard:build; git diff --cached --check.
Assumptions: Bridge recent_deposits created_at is the authoritative source time for deposit activity; rows without created_at must be deduped to their earliest observed status instead of the latest replay ingestion.
Still fake: No fund movement or bridge migration was performed; ntfy messages already sent before this fix cannot be unsent.
Proof: npm test (143 passing); npm run operator-dashboard:build; git diff --cached --check.
Assumptions: Derived portfolio/outcome refreshes are only useful for live freshness when the source event is within the same 30s inventory window enforced by request preflight.
Still fake: No live asset migration submitted; legacy btc.omft remains tracked but not converted to nBTC by this change.
Proof: npm test (140 passing); npm run operator-dashboard:build; git diff --cached --check.
Assumptions: Events older than HISTORY_WRITER_DERIVED_REFRESH_MAX_EVENT_AGE_MS are replay/backfill work; writing them remains required, but expensive derived portfolio/outcome refreshes can wait until the writer reaches fresh events.
Still fake: This does not move or migrate BTC assets; it only improves durable catch-up so fresh inventory can reach request preflight.
Proof: npm test (138 passing); npm run operator-dashboard:build; git diff --cached --check.
Assumptions: Bridge deposits expose near_token_id/intents_token_id for credited asset attribution; nBTC is the solver trading reserve while btc.omft.near remains a tracked legacy BTC wrapper.
Still fake: No live asset migration was submitted; existing btc.omft.near balance is only tracked and withdrawable until a separately approved conversion or withdrawal is executed.
Proof: npm test; node --test test/history-writer-static.test.mjs test/kafka-topics.test.mjs test/environment-status-history.test.mjs; node --check src/apps/history-writer.mjs.
Assumptions: Durable history consumers are idempotent by event_id, so from-beginning subscription is safe when a topic has no committed group offset.
Still fake: This protects durable event capture for repo-owned Kafka topics; it does not backfill events that were never published to Kafka.
Proof: npm test; npm run operator-dashboard:build; node --test test/kafka-topics.test.mjs test/environment-status-history.test.mjs test/operator-dashboard.test.mjs test/ops-sentinel-static.test.mjs; node --check src/bus/kafka/topics.mjs src/bus/kafka/consumer.mjs src/bus/kafka/producer.mjs src/apps/history-writer.mjs src/apps/operator-dashboard.mjs src/apps/ops-sentinel.mjs; PYTHONPATH=. python3 test/repo_deployments_test.py; kubectl kustomize deploy/k8s/base.
Assumptions: Redpanda admin topic creation is allowed for repo-owned app topics and uses the same one-partition retention policy as the bootstrap Job.
Still fake: Topic self-creation only repairs repo-owned Kafka topic bootstrap drift; it does not change upstream NEAR Intents availability or prove quote settlement.
Proof: npm test; npm run operator-dashboard:build; node --test test/near-intents-status.test.mjs test/environment-status-history.test.mjs test/operator-dashboard.test.mjs test/operator-dashboard-ui-static.test.mjs test/ops-sentinel-static.test.mjs; PYTHONPATH=. python3 test/repo_deployments_test.py; kubectl kustomize deploy/k8s/base.
Assumptions: NEAR Intents public status page API remains the official upstream environmental-status source; status fingerprint changes are the durable boundary for saving environmental history.
Still fake: This stores and displays official upstream status changes, but it does not create an alternate quote source or make NEAR quoting operational during an upstream pause.
Proof: npm test; npm run operator-dashboard:build; node --test test/near-intents-status.test.mjs test/operator-dashboard.test.mjs test/operator-dashboard-ui-static.test.mjs; PYTHONPATH=. python3 test/repo_deployments_test.py; kubectl kustomize deploy/k8s/base; live normalization against https://status.near-intents.org returned disrupted/upstream paused for the current 1Click quoting pause.
Assumptions: NEAR Intents public status page API is the official upstream disruption source for operator display; relay websocket reachability remains separately observed by ingest and executor state.
Still fake: This does not add an alternate quote source or recover trading while NEAR Intents quoting is paused; it only makes the upstream disruption explicit and separates it from local service freshness.
Proof: npm test; npm run operator-dashboard:build; node --test test/near-intents-ws.test.mjs test/solver-relay-ws.test.mjs; PYTHONPATH=. python3 test/bootstrap_script_static_test.py; PYTHONPATH=. python3 test/render_release_manifest_test.py; PYTHONPATH=. python3 test/repo_deployments_test.py; PYTHONPATH=. python3 test/ntfy_manifest_test.py; kubectl kustomize deploy/k8s/base.
Assumptions: nested error events emitted during WebSocket close are the same close attempt, not independent evidence that should be logged twice.
Still fake: Notification emissions are limited to credited deposits, completed withdrawals, and completed trades with durable inventory movement; generic alert notification policy remains disabled.
Proof: npm test; npm run operator-dashboard:build; PYTHONPATH=. python3 test/render_release_manifest_test.py; PYTHONPATH=. python3 test/repo_deployments_test.py; PYTHONPATH=. python3 test/ntfy_manifest_test.py; kubectl kustomize deploy/k8s/base.
Assumptions: notifications should be emitted by history-writer after durable writes and outcome refreshes, and only for credited deposits, completed withdrawals, and completed trades with linked inventory movement evidence.
Still fake: Generic alert notification policy is not re-enabled; withdrawal submitted notifications are not emitted; old historical outcomes are not backfilled as notifications; fee-complete realized PnL is still unavailable.
Proof: npm test; PYTHONPATH=. python3 test/render_release_manifest_test.py; PYTHONPATH=. python3 test/repo_deployments_test.py; PYTHONPATH=. python3 test/ntfy_manifest_test.py; kubectl kustomize deploy/k8s/base.
Assumptions: ntfy is a shared cluster utility owned by ../unrip3, while this app repo only consumes the internal ntfy endpoint and keeps publisher-side client/config.
Still fake: No public ntfy ingress, auth token, iOS subscription, or runtime notification emission path is wired yet.
Proof: npm test; PYTHONPATH=. python3 test/render_release_manifest_test.py; PYTHONPATH=. python3 test/repo_deployments_test.py; PYTHONPATH=. python3 test/ntfy_manifest_test.py; kubectl kustomize deploy/k8s/base.
Assumptions: ntfy should start as an internal ClusterIP utility so repo-owned services can publish without exposing an unauthenticated public notification endpoint; mobile delivery needs a separate authenticated ingress or external endpoint decision.
Still fake: No public ntfy ingress or operator mobile subscription exists yet; no existing runtime path emits ntfy notifications by default; ntfy cache storage is ephemeral emptyDir.
Proof: npm test; npm run operator-dashboard:build; PYTHONPATH=. python3 test/render_release_manifest_test.py; PYTHONPATH=. python3 test/repo_deployments_test.py
Assumptions: Service freshness timestamps remain snapshot evidence from service state; the UI should show their advancing age rather than imply a refreshed service poll happened.
Still fake: Service health snapshots are not a venue event stream; exact quote settlement still requires durable inventory movement and no submitted-only evidence is treated as a completed trade.
Proof: npm test; npm run operator-dashboard:build; PYTHONPATH=. python3 test/render_release_manifest_test.py; PYTHONPATH=. python3 test/repo_deployments_test.py
Assumptions: Kafka live topics carry normalized quote, decision, command, and execution result envelopes; durable quote outcomes still refresh through history/bootstrap when inventory attribution is recomputed.
Still fake: Venue-native terminal fill events and fee-complete realized PnL remain unavailable; submitted and relay-accepted evidence still cannot prove settlement without durable inventory movement.
Proof: successful trade summary now aggregates gross edge estimates only from completed lifecycle rows with linked settlement evidence; tests prove completed-without-delta rows are excluded.
Assumptions: gross edge estimate is useful operator evidence but remains pre-fee and not venue-native realized PnL.
Still fake: fee-complete realized trade PnL and venue-native terminal fill events remain unavailable.
Proof: quote lifecycle rows now anchor row time and sorting to quote/submission activity instead of later outcome recomputation; regression covers an old 2% not-filled outcome recomputed after a current 0.49% quote.
Assumptions: outcome-only historical rows still belong in lifecycle evidence, but their dashboard recency must come from original command/submission time when quote evidence is not loaded.
Still fake: venue-native terminal fill events and fee-complete realized PnL remain unavailable.