Automation Verification Engineer: Master Local/QA Executable Checklist #337

Closed
opened 2026-06-07 12:14:03 +00:00 by PlasticDigits · 57 comments
PlasticDigits commented 2026-06-07 12:14:03 +00:00 (Migrated from gitlab.com)

Automation Verification Engineer — Master Checklist

Role: Automation Verification Engineer
Goal: Executable, evidence-backed verification of the entire CL8Y DEX dApp and its LocalTerra / QA-server stack before launch.
Environments: LocalTerra (localterra, LCD :1317, RPC :26657), QA server (make start-qa / SSH tunnel), indexer :3001, Vite :5173 or :3000.
Out of scope: Mainnet/testnet production deploys, treasury multisig ceremonies, formal smart-contract audits, infrastructure penetration tests, Prometheus/metrics (not implemented — #200).

References: docs/qa-onboarding.md, docs/qa-invariants.md, docs/testing.md, QA_TEMPLATE.md, docs/runbooks/launch-checklist.md, docs/reviews/20260409T030009Z/RELEASE_READINESS_MATRIX.md, issue #291 (CEX UX), #292 (SDK 53), #293 (slippage).

Item format: Each row is a single verification scenario. Record PASS/FAIL, build SHA (git rev-parse HEAD), browser, wallet, and attach screenshots / tx hashes / API responses as noted.

Sign-off rule: Section LR-00 Launch Readiness must be 100% PASS with no open P0/P1 blockers before calling the dApp launch-ready.


INF-00 — Environment & Stack Provisioning

INF-00-01 — Fresh LocalTerra full stack bootstrap

  • Preconditions: Clean clone; Docker available; Node 24 via nvm; Rust stable.
  • Actions: make setup-cloud-localterra (or make reset && make start && make wait-healthy && make build-optimized && make deploy-local && bash scripts/e2e-start-indexer.sh).
  • Expected: frontend-dapp/.env.local and indexer/.env exist; make has-localterra exit 0; curl -s http://127.0.0.1:3001/health returns OK; Vite serves at :5173.
  • Failure: Missing env files, LCD timeout, indexer crash on migrate, deploy script stale-wasm error.
  • Evidence: Terminal log tail; make status; .qa-deploy-stamp contents; indexer startup log first 50 lines.
  • Cleanup: None (baseline stack). Repeatability: Use QA_FRESH_VOLUMES=1 make start-qa when prior volume suspected stale.

INF-00-02 — Q1 deploy verification (schema + stamp)

  • Preconditions: Stack from INF-00-01.
  • Actions: make qa-verify-deploy.
  • Expected: Exit 0; LCD is_paused and expired_limit_refund queries succeed; stamp git_sha matches git rev-parse HEAD.
  • Failure: unknown variant on LCD queries (stale chain volume); stamp mismatch after git pull without redeploy.
  • Evidence: scripts/qa/verify-deploy.sh stdout; pair address from .env.local.
  • Cleanup: make reset-qa if schema probe fails.

INF-00-03 — QA server idempotent restart

  • Preconditions: Prior successful QA deploy on same host.
  • Actions: make stop-qa && make start-qa (no fresh volumes).
  • Expected: Indexer reconnects; frontend env unchanged; make qa-verify-deploy still passes if HEAD unchanged.
  • Failure: Port conflicts on 3001/5432; indexer connects to wrong FACTORY_ADDRESS.
  • Evidence: make status; lsof -i :3001; indexer log FACTORY_ADDRESS line.
  • Cleanup: make stop-qa.

INF-00-04 — Postgres role invariant (PG-1)

  • Preconditions: Compose Postgres up.
  • Actions: make setup-indexer-postgres or inspect indexer/.env DATABASE_URL; run make test-indexer-integration (subset: cargo test --test security -- --test-threads=1).
  • Expected: DB user cl8y_legal (not legacy postgres only); migrations apply.
  • Failure: password authentication failed for user cl8y_legal.
  • Evidence: indexer/.env redacted URL host/user; migration log.
  • Cleanup: N/A.

INF-00-05 — Node 24 PATH for frontend dev

  • Preconditions: Cloud Agent or mixed PATH with /exec-daemon/node v22.
  • Actions: make dev (not bare npm run dev); open http://127.0.0.1:5173 in Chrome.
  • Expected: Page loads without "Aw, Snap!"; node -v in dev script is v24.x per .nvmrc.
  • Failure: Chrome crash on load; wrong Node in Vite process.
  • Evidence: ps aux | grep vite; browser screenshot.
  • Cleanup: Kill stale Vite; restart via make dev.

CFG-00 — Configuration & Environment Matrix

CFG-00-01 — Local network env wiring

  • Preconditions: deploy-local completed.
  • Actions: Inspect frontend-dapp/.env.local: VITE_NETWORK=local, VITE_LCD_URL, VITE_RPC_URL, VITE_FACTORY_ADDRESS, VITE_ROUTER_ADDRESS, VITE_INDEXER_URL=http://127.0.0.1:3001.
  • Expected: All addresses terra1…; indexer URL matches running API.
  • Failure: Placeholder addresses; VITE_INDEXER_URL pointing at dead host.
  • Evidence: Redacted .env.local paste; browser Network tab route/solve host.
  • Cleanup: Re-run make deploy-local.

CFG-00-02 — CORS localhost vs 127.0.0.1

  • Preconditions: Indexer running; note CORS_ORIGINS in indexer/.env.
  • Actions: Open dApp at http://localhost:5173 and separately at http://127.0.0.1:5173; trigger indexer fetch (Swap quote or Charts).
  • Expected: Both origins succeed (no CORS error in console).
  • Failure: Access-Control-Allow-Origin missing for one spelling (#131).
  • Evidence: Browser console CORS errors; indexer/.env CORS_ORIGINS line.
  • Cleanup: Add both origins; restart indexer.

CFG-00-03 — Simulated wallet dev-only gate

  • Preconditions: frontend-dapp/.env.development with VITE_DEV_MODE=true, VITE_DEV_MNEMONIC.
  • Actions: Open wallet modal locally; run npm run build and confirm prod build rejects dev mnemonic (vite.config.ts guard).
  • Expected: Simulated Wallet visible in dev; absent in production build artifact.
  • Failure: Mnemonic in prod bundle.
  • Evidence: Wallet modal screenshot; build log error if mnemonic in prod env.
  • Cleanup: N/A.

CFG-00-04 — Expert Mode / slippage settings persistence

  • Preconditions: Connected wallet on Swap.
  • Actions: Enable Expert Mode (if gated); set custom slippage; reload page.
  • Expected: Settings persist via localStorage; retail submit still blocks >30% slippage unless Expert on (#293).
  • Failure: Slippage resets silently; expert bypass without acknowledgement.
  • Evidence: localStorage keys screenshot; blocked submit UI for 35% slippage quote.
  • Cleanup: Clear site data to reset.

WL-00 — Wallets & Authentication

WL-00-01 — Keplr connect on LocalTerra (primary local wallet)

  • Preconditions: Keplr extension with LocalTerra network; stack up.
  • Actions: Connect Wallet → Keplr → approve; note header address chip.
  • Expected: terra1… truncated address; LUNC balance chip loads (#frontend.md).
  • Failure: Wrong chain; infinite spinner.
  • Evidence: Screenshot; Keplr network name.
  • Cleanup: Disconnect.

WL-00-02 — Station on LocalTerra fee/signing limitation

  • Preconditions: Station extension on LocalTerra.
  • Actions: Attempt small swap with Station; compare with Keplr or Simulated Wallet on same amount.
  • Expected: Document outcome: Station may fail fee broadcast on LocalTerra (#235) — do not count as dApp regression if Keplr/simulated succeed.
  • Failure (product): Keplr/simulated also fail.
  • Evidence: Tx error message; wallet type in notes.
  • Cleanup: N/A.

WL-00-03 — Simulated wallet E2E parity

  • Preconditions: VITE_DEV_MODE=true; dev mnemonic funded by deploy script.
  • Actions: Connect Simulated Wallet; execute swap on EMBER→CORAL (or deploy default pair).
  • Expected: Address terra1x46rqay4d3cssq8gxxvqz8xt6nwlz4td20k38v; tx confirms; balances update.
  • Failure: Insufficient funds; signing error.
  • Evidence: Tx hash; LCD tx query.
  • Cleanup: None.

WL-00-04 — Extension not installed UX

  • Preconditions: Disable Keplr extension (or use clean profile).
  • Actions: Open wallet modal → Keplr row.
  • Expected: Dimmed row + Install link; no duplicate "Not installed" badge (#160).
  • Failure: Row shows Ready incorrectly.
  • Evidence: Screenshot.
  • Cleanup: Re-enable extension; refocus window to refresh (#139).

WL-00-05 — WalletConnect session (Cosmostation mobile)

  • Preconditions: Mobile wallet app; desktop dApp on same network.
  • Actions: Connect via WalletConnect QR; approve session; disconnect from dApp.
  • Expected: QR → connected → clean disconnect without ghost session.
  • Failure: QR timeout without message; stuck "connecting".
  • Evidence: Screenshot of QR and connected state.
  • Cleanup: Disconnect both sides.

WL-00-06 — Reject transaction recovery

  • Preconditions: Any connected extension wallet.
  • Actions: Start swap → reject in wallet popup.
  • Expected: UI returns to ready state; actionable "rejected" message; no stuck "pending" forever.
  • Failure: Button disabled permanently.
  • Evidence: Screenshot before/after.
  • Cleanup: Refresh if stuck.

WL-00-07 — Leap wallet absent

  • Preconditions: Wallet modal open.
  • Actions: Search list for Leap.
  • Expected: Leap not listed (#159).
  • Failure: Leap row or broken install URL.
  • Evidence: Screenshot.
  • Cleanup: N/A.

NAV-00 — Navigation, Routing & Global Shell

NAV-00-01 — Primary route reachability

  • Preconditions: Stack up; no wallet required.
  • Actions: Visit /, /trade, /limits, /pool, /create, /charts, /portfolio, /tiers, /protocol; use header nav and mobile menu.
  • Expected: Each route renders without white screen; active nav highlight correct.
  • Failure: 404 blank; chunk load error without recovery.
  • Evidence: Screenshot per route; console errors.
  • Cleanup: N/A.
  • Preconditions: Factory pair address from .env.local or pool list.
  • Actions: Navigate to /trade/<pairAddr> directly; reload.
  • Expected: Correct pair selected; chart and book load.
  • Failure: Fallback to wrong pair; crash on invalid address.
  • Evidence: URL bar; pair symbol displayed.
  • Cleanup: N/A.

NAV-00-03 — Invalid route handling

  • Preconditions: None.
  • Actions: Visit /nonexistent, /trade/not-a-terra-address.
  • Expected: Redirect home or friendly empty state (#291 EH-5).
  • Failure: Uncaught exception white screen.
  • Evidence: Screenshot; console stack.
  • Cleanup: N/A.

NAV-00-04 — Theme persistence

  • Preconditions: None.
  • Actions: Toggle light/dark/system; reload.
  • Expected: Theme persists (localStorage); no flash of wrong theme >1s.
  • Failure: Reset to default every reload.
  • Evidence: Screenshot both themes.
  • Cleanup: N/A.

NAV-00-05 — /my-portfolio redirect

  • Preconditions: None.
  • Actions: Navigate to /my-portfolio.
  • Expected: Redirect to /portfolio.
  • Failure: 404.
  • Evidence: Network tab 302/redirect.
  • Cleanup: N/A.

SW-00 — Swap (/)

SW-00-01 — Direct pool swap (on-chain tx)

  • Preconditions: Simulated or Keplr wallet; pair EMBER/CORAL with liquidity.
  • Actions: Select tokens; enter 10 EMBER; review min received, price impact, route row; submit.
  • Expected: Single-hop route; tx succeeds; receive amount within slippage tolerance; success toast with explorer link.
  • Failure: Simulation error; tx fail on chain; amount mismatch > slippage.
  • Evidence: Tx hash; before/after CW20 balances via LCD; UI screenshot.
  • Cleanup: None.

SW-00-02 — Multi-hop router swap

  • Preconditions: Wallet funded; token pair requiring ≥2 hops (e.g. token without direct pool).
  • Actions: Swap with indexer route showing ≥2 hops; submit via router path.
  • Expected: Route display shows ordered hops (#158 single Route row); router tx succeeds.
  • Failure: Duplicate/conflicting route lines; router ops mismatch submit payload.
  • Evidence: Network route/solve JSON; tx event wasm attributes.
  • Cleanup: None.

SW-00-03 — Wrap native LUNC swap path

  • Preconditions: Wallet with uluna; Wrap-Mapper deployed.
  • Actions: Swap from native LUNC to CW20 (or reverse) using wrap/unwrap toggles.
  • Expected: Auto-wrap path clear; tx includes wrap mapper leg if needed.
  • Failure: Insufficient native for wrap gas; wrong denom in tx.
  • Evidence: Tx messages JSON; wrap-swap.spec.ts parity.
  • Cleanup: None.

SW-00-04 — Slippage enrichment and retail guard (#293)

  • Preconditions: Indexer fresh deploy (--fresh if needed); pair with known arb asymmetry (EMBER→CORAL per make verify-issue-293).
  • Actions: Enter amount triggering >30% slippage_percent on route solve; attempt submit without Expert Mode.
  • Expected: Submit blocked; warning shows slippage % and spot comparison; Expert Mode allows with acknowledgement.
  • Failure: Submit allowed at 50% slippage retail; missing slippage_percent when assets clean.
  • Evidence: GET /api/v1/route/solve?... response fields; UI screenshot; make verify-issue-293 output.
  • Cleanup: Fresh indexer DB if duplicate USTC-C assets.

SW-00-05 — Max button gas reserve

  • Preconditions: Wallet with mixed native + CW20.
  • Actions: Click Max on native-denom swap.
  • Expected: Amount leaves LUNC reserve for gas (#291 OE-7).
  • Failure: Tx fails out of gas after Max.
  • Evidence: Input value vs wallet balance; tx result.
  • Cleanup: N/A.

SW-00-06 — Swap during indexer outage

  • Preconditions: E2E_INDEXER_OUTAGE=1 path or stop indexer; LCD up.
  • Actions: Load Swap; enter amount.
  • Expected: Market-data banner; LCD fallback quote or honest degradation; pool-only path may still work.
  • Failure: Infinite spinner; silent wrong quote.
  • Evidence: Banner screenshot; swap-indexer-outage.spec.ts parity.
  • Cleanup: Restart indexer.

SW-00-07 — Fee tier discount on quote

  • Preconditions: Wallet registered on Fee Discount tier with CL8Y balance; tier active.
  • Actions: Compare quoted fee before/after registration on same pair.
  • Expected: Lower effective fee after tier; matches fee-discount-quote-245 E2E.
  • Failure: Discount not applied in simulation or tx.
  • Evidence: LCD hybrid_simulation with sender; tier page status.
  • Cleanup: Deregister if test changed state.

SW-00-08 — Hybrid swap disclosure (when hybrid enabled)

  • Preconditions: LocalTerra with limit book liquidity on pair.
  • Actions: Swap amount crossing pool+book; read hybrid disclosure / doc link.
  • Expected: Hybrid leg breakdown shown; matches hybrid-swap.spec.ts.
  • Failure: Pool-only UI while on-chain hybrid executed.
  • Evidence: Tx pool_return_amount / book_return_amount attrs; screenshot.
  • Cleanup: None.

SW-00-09 — Pause banner blocks swap

  • Preconditions: Pair paused on-chain (governance test pair or local admin if available).
  • Actions: Attempt swap on paused pair.
  • Expected: Banner + disabled submit with clear copy (#87).
  • Failure: Tx broadcast then fail obscurely.
  • Evidence: LCD is_paused; UI screenshot.
  • Cleanup: Unpause pair.

TR-00 — Trade Workspace (/trade)

TR-00-01 — Initial load layout

  • Preconditions: Indexer + LCD up; default pair.
  • Actions: Open /trade; wait for chart, book, market panel.
  • Expected: No CLS >0.1 on pair header; skeletons resolve (trade-page-initial-load.spec.ts).
  • Failure: Overlapping panels; chart never mounts.
  • Evidence: Screenshot; Lighthouse CLS optional.
  • Cleanup: N/A.

TR-00-02 — Market order panel execution

  • Preconditions: Connected wallet.
  • Actions: Market tab: enter size; submit market swap.
  • Expected: Same routing semantics as Swap page for execution path (#158).
  • Failure: Different route than Swap for identical inputs.
  • Evidence: Side-by-side route rows; tx hash.
  • Cleanup: None.

TR-00-03 — Limit ticket place + view order

  • Preconditions: Wallet with offer token; pair with book.
  • Actions: Place limit from ticket; on success click View order.
  • Expected: Scroll/highlight to indexed placement row (#161).
  • Failure: Order not in list after 30s poll; poll error silent.
  • Evidence: Console for [limit-place] indexer poll failed; placement order_id.
  • Cleanup: Cancel order.

TR-00-04 — Order book edit mode

  • Preconditions: Deep book data.
  • Actions: Enter book edit mode; modify level; cancel edit.
  • Expected: Edit affordances per #178; no orphan modal.
  • Failure: Edit persists without save.
  • Evidence: Screenshot; trade-book-edit-178.spec.ts.
  • Cleanup: Discard edits.

TR-00-05 — Pair selector search CLS

  • Preconditions: Many pairs indexed.
  • Actions: Open pair dropdown; type filter; select pair.
  • Expected: No layout jump (trade-pair-select-cls.spec.ts).
  • Failure: List reflow shifts chart.
  • Evidence: Screen recording.
  • Cleanup: N/A.

TR-00-06 — Trade page indexer outage

  • Preconditions: Indexer down; LCD up.
  • Actions: Load /trade.
  • Expected: Outage banner; chart/history degrade honestly (trade-indexer-outage.spec.ts).
  • Failure: Fake stale prices labeled live.
  • Evidence: Banner + last-updated timestamps.
  • Cleanup: Restart indexer.

TR-00-07 — Responsive trade layout

  • Preconditions: Playwright mobile viewport or DevTools iPhone 14.
  • Actions: Complete market swap flow on mobile width.
  • Expected: Tap targets ≥44px; no horizontal scroll (trade-page-responsive.spec.ts).
  • Failure: Submit button off-screen.
  • Evidence: Screenshot 390px width.
  • Cleanup: N/A.

LT-00 — Limit Orders (/limits)

LT-00-01 — Single limit place + cancel (tx)

  • Preconditions: Funded wallet; pair with book.
  • Actions: Place single limit; wait indexer; cancel; confirm escrow returned.
  • Expected: Open order appears; cancel tx succeeds; row removed from active list (#135).
  • Failure: Cancelled id still in active placements API.
  • Evidence: Tx hashes; GET .../limit-placements before/after.
  • Cleanup: None.

LT-00-02 — Batch limit placement

  • Preconditions: Wallet with sufficient offer token.
  • Actions: Place batch of 3 limits at distinct prices.
  • Expected: All 3 on-chain; indexer lists all; gas acceptable.
  • Failure: Partial batch without error surfacing.
  • Evidence: Tx events; API rows.
  • Cleanup: Cancel all.

LT-00-03 — Ladder placement UI + tx (#295)

  • Preconditions: Ladder tab on /limits.
  • Actions: Clear rung count (stays empty); type 3; type 25 rungs (inline max error); blur (clamps to 20); submit valid ladder.
  • Expected: Inline validation per verify-issue-295-ladder-rung-ui.spec.ts; ladder tx succeeds.
  • Failure: Empty field becomes 0; accepts 25 rungs.
  • Evidence: Screenshot validation states; make verify-issue-295.
  • Cleanup: Cancel ladder orders.

LT-00-04 — Gas presets on limit place (#204)

  • Preconditions: Gas preset selector visible.
  • Actions: Select high gas preset; place limit; inspect tx gas wanted.
  • Expected: max_adjust_steps matches preset mapping (verify-glab-204-limit-gas-presets.sh).
  • Failure: Default gas on all presets.
  • Evidence: Tx simulation gas; script output.
  • Cleanup: Cancel order.

LT-00-05 — Claim expired parked order

  • Preconditions: Expired parked limit on-chain (wait expiry or seed).
  • Actions: Claim refund from UI.
  • Expected: Escrow returned; lifecycle refunded in API (#142).
  • Failure: Claim during pair pause succeeds (should fail L6).
  • Evidence: LCD + API lifecycle_status.
  • Cleanup: N/A.

LT-00-06 — Claim all expired batch

  • Preconditions: Multiple parked expired orders.
  • Actions: Use Claim All control.
  • Expected: Batch claim tx; all rows transition (limit-orders-claim-all-tx.spec.ts).
  • Failure: Partial claim without UI feedback.
  • Evidence: Tx hash; API diff.
  • Cleanup: N/A.

LT-00-07 — Deep order book pagination

  • Preconditions: Book depth > one page.
  • Actions: Paginate limit-book UI; cross-check indexer GET .../limit-book?cursor=.
  • Expected: Consistent ordering; no duplicate levels (#267 gap handling).
  • Failure: Cursor loop; missing pagination_gap when walk incomplete.
  • Evidence: API JSON pages; screenshot.
  • Cleanup: N/A.

LT-00-08 — Limits page indexer outage

  • Preconditions: Indexer stopped.
  • Actions: Open /limits.
  • Expected: Banner; LCD shallow book fallback if implemented.
  • Failure: Empty book with no explanation.
  • Evidence: limits-indexer-outage.spec.ts parity.
  • Cleanup: Restart indexer.

PL-00 — Pool & Liquidity (/pool)

PL-00-01 — Pool list search, sort, pagination

  • Preconditions: Indexer synced post-deploy (~23 pairs).
  • Actions: Search "EMBER"; sort by 24h volume desc; paginate.
  • Expected: Correct filtering; page bounds disable (#291 PL-1..PL-3).
  • Failure: Indexer-only pairs missing badge context.
  • Evidence: Screenshot; API GET /api/v1/pairs?.
  • Cleanup: N/A.

PL-00-02 — Add liquidity (tx)

  • Preconditions: Wallet with both assets + LUNC gas.
  • Actions: Provide liquidity non-proportional ratio; confirm warning; submit.
  • Expected: Two-step allowance + provide; LP balance increases (pool-tx.spec.ts).
  • Failure: Tx fail; LP not credited.
  • Evidence: Tx hash; LP token balance LCD.
  • Cleanup: Withdraw liquidity.

PL-00-03 — Remove liquidity (tx)

  • Preconditions: LP tokens from PL-00-02.
  • Actions: Withdraw 50% with 1% slippage preset.
  • Expected: Assets returned; pool reserves update.
  • Failure: Insufficient LP guard bypass.
  • Evidence: Tx hash; reserves before/after.
  • Cleanup: N/A.

PL-00-04 — Wrap in provide liquidity

  • Preconditions: Native LUNC only for one side.
  • Actions: Provide with wrap toggle for native side.
  • Expected: Wrap + provide succeeds (wrap-pool.spec.ts).
  • Failure: Wrong denom in provide msg.
  • Evidence: Tx messages.
  • Cleanup: Withdraw if needed.

PL-00-05 — Router-known vs indexer-only badge

  • Preconditions: Deploy includes unpaired/minimal pairs.
  • Actions: Toggle "Router-known (factory) only" filter.
  • Expected: Badges accurate (#291 PL-4).
  • Failure: Factory pair hidden incorrectly.
  • Evidence: Screenshot filter on/off.
  • Cleanup: N/A.

CP-00 — Create Pair (/create)

CP-00-01 — Validation gates

  • Preconditions: Wallet connected.
  • Actions: Enter invalid address; identical token A/B; non-whitelisted code ID token (ROGUE).
  • Expected: Inline errors; submit disabled (#291 CP-1..CP-3).
  • Failure: Tx broadcast for invalid pair.
  • Evidence: Screenshot errors.
  • Cleanup: N/A.

CP-00-02 — Successful pair creation (tx)

  • Preconditions: Two whitelisted unused tokens; uluna creation fee.
  • Actions: Create pair; wait confirmation.
  • Expected: Factory PairCreated event; pair appears in list (create-pair.spec.ts).
  • Failure: Insufficient uluna without pre-check.
  • Evidence: Tx hash; factory query pair count.
  • Cleanup: Pair remains (acceptable on local).

FT-00 — Fee Tiers (/tiers)

FT-00-01 — Tier ladder display

  • Preconditions: Fee Discount deployed with 11 tiers.
  • Actions: Load /tiers; compare to docs/reference/fee-discount-tiers.md.
  • Expected: Holdings, discount %, effective fee match doc; make check-fee-discount-tier-docs passes.
  • Failure: Drift vs tier_fixtures.rs.
  • Evidence: Screenshot; make target output.
  • Cleanup: N/A.

FT-00-02 — Register + deregister tier (tx)

  • Preconditions: Wallet with sufficient CL8Y for tier 1.
  • Actions: Register; verify swap fee reduction; deregister.
  • Expected: Status updates; on-chain tier cleared (fee-tier-tx.spec.ts).
  • Failure: Governance-only tier self-register enabled.
  • Evidence: Tx hashes; tier query.
  • Cleanup: Deregister.

PF-00 — Portfolio & Trader Profiles

PF-00-01 — Portfolio balances and positions

  • Preconditions: Wallet with LP + open limits + swap history.
  • Actions: Open /portfolio connected.
  • Expected: Balances match chain; positions table loads (#212); open limits (#217).
  • Failure: Stale balances after trade without refresh.
  • Evidence: Screenshot; compare LCD bank balances.
  • Cleanup: N/A.

PF-00-02 — Wallet swap/limit history (#163)

  • Preconditions: Prior swaps and limits on connected address.
  • Actions: Open history sections; export CSV if available.
  • Expected: Rows match indexer GET /api/v1/traders/{addr}/trades?format=csv.
  • Failure: Empty history with indexed rows.
  • Evidence: CSV download; API response.
  • Cleanup: N/A.

PF-00-03 — Public trader page

  • Preconditions: Known trader address (own or swarm bot).
  • Actions: Visit /trader/<addr>; reload; switch address in URL.
  • Expected: PnL color coding; shareable URL (#291 TR-1..TR-3).
  • Failure: Crash on invalid address.
  • Evidence: Screenshot; API 404 handling.
  • Cleanup: N/A.

CH-00 — Charts (/charts & Trade chart)

CH-00-01 — Candle intervals after seed-qa

  • Preconditions: cd indexer && cargo run -- seed-qa; indexer restarted.
  • Actions: Open Charts; pair with seeded data; switch 1m/1h/1d/1w.
  • Expected: Non-empty candles for seeded window (#113 empty = success not error).
  • Failure: Error state on empty []; chart crash.
  • Evidence: Screenshot per interval; API GET .../candles?interval=.
  • Cleanup: cargo run -- seed-qa --clean optional.

CH-00-02 — Chart matches last trade

  • Preconditions: Recent swap on pair.
  • Actions: Compare chart last price to GET .../trades?limit=1.
  • Expected: Prices align within rounding.
  • Failure: >1% drift without stale indicator.
  • Evidence: Screenshot + API JSON.
  • Cleanup: N/A.

CH-00-03 — Charts indexer outage

  • Preconditions: Indexer down.
  • Actions: Load /charts.
  • Expected: Outage banner; no uncaught exception (charts-indexer-outage.spec.ts).
  • Failure: White screen.
  • Evidence: Screenshot.
  • Cleanup: Restart indexer.

CH-00-04 — Price chart smoke (indicators)

  • Preconditions: Seeded or live data.
  • Actions: Enable MA/RSI on trade chart if exposed.
  • Expected: Indicators render (price-chart-smoke.spec.ts, test-frontend-charts).
  • Failure: NaN lines; autoscale break (#229).
  • Evidence: Screenshot.
  • Cleanup: N/A.

PR-00 — Protocol & Oracle (/protocol)

PR-00-01 — Oracle price display

  • Preconditions: Indexer oracle feed running.
  • Actions: Load /protocol; note USTC/USD price, source, fetched-at.
  • Expected: Values match GET /api/v1/oracle/price.
  • Failure: Stale timestamp without warning.
  • Evidence: Screenshot; API response.
  • Cleanup: N/A.

PR-00-02 — Hook events feed

  • Preconditions: Pairs with hooks deployed (if any on local).
  • Actions: Filter hook events table by contract.
  • Expected: Rows with tx links; empty state if none.
  • Failure: 500 surfaced raw to user.
  • Evidence: API GET /api/v1/hooks.
  • Cleanup: N/A.

IDX-00 — Indexer API & Sync

IDX-00-01 — Health and Swagger

  • Preconditions: Indexer running.
  • Actions: GET /health; open /swagger-ui.
  • Expected: Health OK; documented routes load.
  • Failure: 404 swagger; health DB false.
  • Evidence: curl output; screenshot.
  • Cleanup: N/A.

IDX-00-02 — Route solve GET global best execution

  • Preconditions: Router address in indexer env.
  • Actions: GET /api/v1/route/solve?token_in=...&token_out=...&amount_in=1000000 with hybrid-capable pair.
  • Expected: estimated_amount_out, solver_version, paths_considered; 502 not raw LCD leak (#239).
  • Failure: Internal server error with SQL text; LCD stack in body.
  • Evidence: Redacted JSON response; indexer log trace.
  • Cleanup: N/A.

IDX-00-03 — Route solve POST hybrid_by_hop length validation

  • Preconditions: Indexer up.
  • Actions: POST with hybrid_by_hop length ≠ hop count.
  • Expected: HTTP 400 generic message.
  • Failure: 500 panic.
  • Evidence: curl -d JSON; response body.
  • Cleanup: N/A.

IDX-00-04 — Security caps (limit injection)

  • Preconditions: Indexer up.
  • Actions: GET /api/v1/pairs/.../candles?interval=1m';DROP TABLE-- and limit=-1.
  • Expected: 400 bad interval; limit clamps to 1 not 500 (#243).
  • Failure: 500; negative LIMIT.
  • Evidence: make test-indexer-integration security tests log.
  • Cleanup: N/A.

IDX-00-05 — Indexer sync after swap

  • Preconditions: Note latest indexed height.
  • Actions: Execute swap; wait ≤30s.
  • Expected: New row in GET .../trades; candle bucket updates.
  • Failure: No sync after 2 min while chain progresses.
  • Evidence: Trade API row tx_hash; indexer log block height.
  • Cleanup: N/A.

IDX-00-06 — CG/CMC compliance shapes

  • Preconditions: Indexer up.
  • Actions: GET /cg/orderbook?ticker_id=...; GET /cmc/orderbook/{pair}.
  • Expected: CG object; CMC array of one book (#223); timestamps numeric ms/s (#222).
  • Failure: Wrong JSON shape.
  • Evidence: curl JSON snippets.
  • Cleanup: N/A.

IDX-00-07 — Hybrid volume L10 reconciliation

  • Preconditions: Hybrid swap indexed.
  • Actions: Compare swap row return_amount to pool_leg_volume + book_leg_volume.
  • Expected: pool + book = return on ask side (#216).
  • Failure: Double-count in ticker volume.
  • Evidence: API trade row; api_integrator_hybrid_volume test reference.
  • Cleanup: N/A.

IDX-00-08 — Lifecycle emitter scoping (#285)

  • Preconditions: LocalTerra with test harness or make verify-issue-285.
  • Actions: Run verification script.
  • Expected: Forged contract_address does not attribute lifecycle to victim pair.
  • Failure: Victim pair shows attacker's fill.
  • Evidence: make verify-issue-285 output.
  • Cleanup: N/A.

ONC-00 — On-Chain Contracts (functional, not audit)

ONC-00-01 — Smoke pool swap script

  • Preconditions: Deploy complete.
  • Actions: bash scripts/smoke-pool-swap.sh.
  • Expected: LCD pool query OK; simulation succeeds pool-only.
  • Failure: Non-zero exit.
  • Evidence: Script stdout.
  • Cleanup: N/A.

ONC-00-02 — Factory pause semantics

  • Preconditions: Ability to pause pair via factory (local gov key).
  • Actions: Pause pair; attempt swap and limit place; unpause.
  • Expected: Swap/place blocked; cancel refund path works (#87).
  • Failure: Swap succeeds while paused.
  • Evidence: LCD queries; tx errors.
  • Cleanup: Unpause.

ONC-00-03 — Fee discount trusted router

  • Preconditions: Router deployed.
  • Actions: Query is_trusted_router on Fee Discount contract.
  • Expected: true for production router address.
  • Failure: false while UI assumes router discounts.
  • Evidence: LCD query JSON.
  • Cleanup: N/A.

ONC-00-04 — Hybrid simulation vs execution (L8)

  • Preconditions: Book liquidity exists.
  • Actions: hybrid_simulation then matching hybrid execute same params.
  • Expected: Output within documented tolerance (limit_order_tests.rs L8).
  • Failure: >1% drift sim vs exec.
  • Evidence: LCD sim JSON; tx result attributes.
  • Cleanup: N/A.

ERR-00 — Error Recovery & Degraded Modes

ERR-00-01 — LCD outage during quote

  • Preconditions: Stop LocalTerra container briefly or block LCD port.
  • Actions: Request swap quote.
  • Expected: User-visible LCD error; retry affordance; no white screen.
  • Failure: Cached fake quote.
  • Evidence: Screenshot; network failed requests.
  • Cleanup: make start.

ERR-00-02 — ErrorBoundary recovery

  • Preconditions: DevTools open (optional forced error route if exists).
  • Actions: Trigger render error boundary (known test hook or invalid props via chaos).
  • Expected: Recovery UI with reload action (#291 EH-4).
  • Failure: Blank white page.
  • Evidence: Screenshot.
  • Cleanup: Reload.

ERR-00-03 — Tx broadcast timeout

  • Preconditions: Simulate slow RPC (throttle) if possible.
  • Actions: Submit swap; wait past timeout threshold.
  • Expected: Actionable timeout message; user can retry without refresh.
  • Failure: Infinite pending.
  • Evidence: UI state after 2 min; console logs.
  • Cleanup: N/A.

ERR-00-04 — Insufficient balance preflight

  • Preconditions: Wallet with 1 token only.
  • Actions: Attempt swap exceeding balance.
  • Expected: Blocked before wallet popup (#291 EH-2).
  • Failure: Wallet opens then fails obscurely.
  • Evidence: Screenshot disabled button/tooltip.
  • Cleanup: N/A.

CON-00 — Concurrency & Load (local/QA only)

CON-00-01 — Trading swarm stress

  • Preconditions: make swarm-local or make swarm-launch prerequisites met.
  • Actions: Run swarm 5–10 min; use dApp concurrently on /trade.
  • Expected: UI remains responsive; indexer rate limits 429 not crash.
  • Failure: OOM indexer; dApp freeze.
  • Evidence: make status; indexer memory; screenshot UI still interactive.
  • Cleanup: Stop swarm.

CON-00-02 — Parallel Playwright e2e-tx isolation

  • Preconditions: LocalTerra up.
  • Actions: make test-e2e-tx (1 worker by design).
  • Expected: All tx specs pass serialized without nonce collisions.
  • Failure: Account sequence mismatch failures.
  • Evidence: Playwright report.
  • Cleanup: Fresh deploy if sequence corrupted.

CON-00-03 — Duplicate tab quote consistency

  • Preconditions: Two tabs on Swap same pair.
  • Actions: Enter amount in tab A; switch tab B same amount.
  • Expected: Quotes match within refresh window.
  • Failure: Divergent routes without amount change.
  • Evidence: Side-by-side screenshots.
  • Cleanup: Close tabs.

XBR-00 — Cross-Browser (local)

XBR-00-01 — Chrome desktop (primary)

  • Preconditions: Stack up.
  • Actions: Execute SW-00-01 in Chrome latest.
  • Expected: Pass.
  • Failure: Any regression vs baseline.
  • Evidence: As SW-00-01.
  • Cleanup: N/A.

XBR-00-02 — Firefox desktop swap smoke

  • Preconditions: Firefox installed.
  • Actions: Connect Keplr FF or simulated; one swap.
  • Expected: Functional parity for core flow.
  • Failure: Wallet connect broken entirely.
  • Evidence: Screenshot; tx hash or block reason.
  • Cleanup: N/A.

XBR-00-03 — Playwright Chromium automated suite

  • Preconditions: Full stack.
  • Actions: CI=1 make test-e2e (5 workers smoke).
  • Expected: All non-skipped specs green.
  • Failure: Any failure — attach HTML report.
  • Evidence: frontend-dapp/playwright-report/.
  • Cleanup: N/A.

RES-00 — Responsive Layout

RES-00-01 — Mobile navigation stack

  • Preconditions: 390×844 viewport.
  • Actions: Navigate all primary routes via mobile menu.
  • Expected: No trapped views; back works (#291 ME-2).
  • Failure: Modal overflow off-screen.
  • Evidence: Screenshots each route.
  • Cleanup: N/A.

RES-00-02 — Tablet trade layout

  • Preconditions: 768px width.
  • Actions: Place limit from /trade.
  • Expected: Form usable without horizontal scroll.
  • Failure: Overlapping chart on ticket.
  • Evidence: Screenshot.
  • Cleanup: Cancel limit.

A11Y-00 — Accessibility

A11Y-00-01 — Critical routes axe scan

  • Preconditions: Stack up.
  • Actions: Run e2e/a11y-critical-routes.spec.ts or axe DevTools on /, /trade, /limits.
  • Expected: No critical violations; focus visible (#144).
  • Failure: Missing focus ring on swap submit.
  • Evidence: axe report JSON.
  • Cleanup: N/A.

A11Y-00-02 — Keyboard-only swap

  • Preconditions: Desktop; no mouse.
  • Actions: Tab to token selector, amount, submit; activate via Enter/Space.
  • Expected: Full flow completable (#291 AX-1).
  • Failure: Focus trap escape impossible.
  • Evidence: Screen recording.
  • Cleanup: N/A.

A11Y-00-03 — Modal focus trap

  • Preconditions: Open wallet modal.
  • Actions: Tab through; Escape close.
  • Expected: Focus trapped inside; restored to trigger on close (#291 AX-2).
  • Failure: Focus lost to background.
  • Evidence: Document.activeElement notes.
  • Cleanup: N/A.

PERF-00 — Performance (local/QA)

PERF-00-01 — Quote latency p95

  • Preconditions: Normal load; indexer warm.
  • Actions: DevTools Performance; 20 quote requests typing amount on Swap.
  • Expected: p95 < 1s for indexer route solve (#291 PR-3).
  • Failure: >3s consistent.
  • Evidence: HAR or Performance trace.
  • Cleanup: N/A.

PERF-00-02 — Trade page memory 30 min

  • Preconditions: /trade open.
  • Actions: Leave 30 min with swarm optional; sample heap.
  • Expected: No runaway growth (#291 PR-4).
  • Failure: >200MB growth without trades.
  • Evidence: Chrome heap snapshot diff.
  • Cleanup: Close tab.

PERF-00-03 — Production bundle no sourcemaps

  • Preconditions: npm run build in frontend-dapp.
  • Expected: No .js.map in dist/ for production mode (#117).
  • Failure: Maps published.
  • Evidence: find dist -name '*.map'.
  • Cleanup: N/A.

SEC-00 — Application Security Behavior (not formal audit)

SEC-00-01 — Blacklist compliance probe

  • Preconditions: Indexer blacklist-check endpoint.
  • Actions: GET /api/v1/compliance/blacklist-check?address=... for known clean and test flagged addresses per docs.
  • Expected: JSON status; dApp surfaces trading block if flagged.
  • Failure: Swap allowed for flagged address without warning.
  • Evidence: API response; UI screenshot.
  • Cleanup: N/A.

SEC-00-02 — Rate limit 429 on abuse

  • Preconditions: RATE_LIMIT_RPS enabled (default 60).
  • Actions: Burst >100 requests/sec to /api/v1/route/solve from single IP.
  • Expected: 429 responses; process stable (#278).
  • Failure: OOM or 500 storm.
  • Evidence: curl loop status codes.
  • Cleanup: Wait cooldown.

SEC-00-03 — CORS rejection

  • Preconditions: Indexer with strict CORS_ORIGINS.
  • Actions: curl -H "Origin: https://evil.example" /api/v1/pairs.
  • Expected: No Access-Control-Allow-Origin for evil origin.
  • Failure: * in production config.
  • Evidence: Response headers.
  • Cleanup: N/A.
  • Preconditions: Swap page loaded.
  • Actions: Verify legal footer links and risk acknowledgement on first swap.
  • Expected: Present per docs/frontend.md risk surfacing; E2E #138 paths pass.
  • Failure: Missing disclosure.
  • Evidence: Screenshot; make test-e2e filter 138 if exists.
  • Cleanup: N/A.

SEC-00-05 — Retail slippage hard block

  • Preconditions: Quote >30% slippage (#293).
  • Actions: Attempt submit without Expert Mode.
  • Expected: Blocked.
  • Failure: Funds at risk via unguarded submit.
  • Evidence: As SW-00-04.
  • Cleanup: N/A.

OBS-00 — Observability & Evidence Collection

OBS-00-01 — Indexer structured logs on block lag

  • Preconditions: Indexer running.
  • Actions: Inspect logs during catch-up after restart.
  • Expected: Block height progress; warnings on slow blocks (#200 scope: logs only).
  • Failure: Silent stall with no log.
  • Evidence: Log excerpt with heights.
  • Cleanup: N/A.
  • Preconditions: Successful swap.
  • Actions: Click tx link in success toast.
  • Expected: Opens correct explorer URL for localterra (or configured explorer).
  • Failure: 404 explorer page.
  • Evidence: URL bar.
  • Cleanup: N/A.
  • Preconditions: Pending tx.
  • Actions: Observe confirming state link (terra-broadcast-confirming-link-tx.spec.ts).
  • Expected: Link becomes clickable when hash known.
  • Failure: Dead link during broadcast.
  • Evidence: Screenshot pending state.
  • Cleanup: N/A.

REG-00 — Automated Regression Gates

REG-00-01 — Contract unit tests

  • Actions: make test-contracts.
  • Expected: All pass.
  • Evidence: CI log or local output.
  • Cleanup: N/A.

REG-00-02 — Frontend unit tests

  • Actions: make test-frontend.
  • Expected: 600+ tests pass Node 24.
  • Evidence: Vitest summary.
  • Cleanup: N/A.

REG-00-03 — Indexer lib tests

  • Actions: cd indexer && cargo test --lib.
  • Expected: Pass without Postgres.
  • Evidence: cargo output.
  • Cleanup: N/A.

REG-00-04 — Indexer integration tests

  • Preconditions: make setup-indexer-postgres.
  • Actions: make test-indexer-integration.
  • Expected: Serialized pass.
  • Evidence: Test summary.
  • Cleanup: N/A.

REG-00-05 — Charts integration

  • Actions: make test-charts-integration.
  • Expected: HTTP + ChartsPage integration pass.
  • Evidence: Output log.
  • Cleanup: N/A.

REG-00-06 — E2E strict on-chain

  • Preconditions: INF-00-01 stack.
  • Actions: CI=1 make test-e2e and make test-e2e-tx.
  • Expected: Green.
  • Evidence: Playwright report paths.
  • Cleanup: N/A.

REG-00-07 — E2E indexer outage project

  • Actions: make test-e2e-indexer-outage.
  • Expected: Green with OUTAGE_E2E_INDEXER_URL dead port.
  • Evidence: Script log.
  • Cleanup: Restart indexer per docs/testing.md.

REG-00-08 — Issue-specific verifiers

  • Actions: make verify-issue-285 && make verify-issue-293 && make verify-issue-295 && make verify-issue-324 (as applicable).
  • Expected: All exit 0 on current stack.
  • Evidence: Script stdout.
  • Cleanup: N/A.

REG-00-09 — Fee tier doc drift

  • Actions: make check-fee-discount-tier-docs.
  • Expected: Exit 0.
  • Evidence: Output.
  • Cleanup: N/A.

REG-00-10 — Lint gates

  • Actions: make lint-contracts && make lint-frontend.
  • Expected: Exit 0.
  • Evidence: Output.
  • Cleanup: N/A.

EDGE-00 — Edge Cases & Boundary Conditions

EDGE-00-01 — Zero amount swap

  • Actions: Enter 0; click swap.
  • Expected: Submit disabled ("Enter Amount").
  • Failure: Wallet popup opens.
  • Evidence: Screenshot.
  • Cleanup: N/A.

EDGE-00-02 — Decimal precision dust

  • Actions: Swap 0.000001 smallest unit.
  • Expected: No scientific notation leak; simulation or min amount error (#291 OE-9).
  • Failure: 1e-18 displayed.
  • Evidence: Screenshot.
  • Cleanup: N/A.

EDGE-00-03 — Non-whitelisted token pair swap attempt

  • Preconditions: ROGUE/BOGUS tokens.
  • Actions: Attempt route through non-whitelisted pair.
  • Expected: Graceful no-route or factory rejection.
  • Failure: UI offers impossible tx.
  • Evidence: Route solve 404/400.
  • Cleanup: N/A.

EDGE-00-04 — Expired limit during match

  • Preconditions: Limit near expiry + matching taker flow.
  • Actions: Execute taker swap as limit expires.
  • Expected: Contract unlinks per limit-orders.md; no maker double-pay.
  • Failure: Stuck escrow.
  • Evidence: On-chain events; API lifecycle.
  • Cleanup: Claim if parked.

EDGE-00-05 — Multi-swap same tx indexing (#287)

  • Preconditions: Router tx with 2 swaps same pair if scenario exists.
  • Actions: Verify indexer creates distinct swap_index rows.
  • Expected: No dedup collision.
  • Failure: Missing second swap in API.
  • Evidence: trades API rows sharing tx_hash.
  • Cleanup: N/A.

EDGE-00-06 — Chunk load failure recovery

  • Preconditions: Throttle network; navigate to lazy route.
  • Actions: Trigger chunk load error.
  • Expected: Retry/reload prompt (#291 PR-5).
  • Failure: Permanent blank.
  • Evidence: Screenshot.
  • Cleanup: Hard reload.

INT-00 — Integration Boundaries

INT-00-01 — Frontend ↔ indexer contract

  • Actions: Compare frontend-dapp/src/services/indexer/client.ts types to live GET /api/v1/pairs schema.
  • Expected: No Zod/runtime parse errors in console on Pool page.
  • Failure: Type drift causes silent drop.
  • Evidence: Console errors.
  • Cleanup: N/A.

INT-00-02 — Frontend ↔ LCD contract

  • Actions: Pool reserves on UI vs LCD pool query.
  • Expected: Match within rounding.
  • Failure: 10%+ reserve drift while LCD healthy.
  • Evidence: LCD JSON + UI screenshot.
  • Cleanup: N/A.

INT-00-03 — Indexer ↔ chain reorg safety (replay)

  • Actions: Restart indexer; re-index same blocks.
  • Expected: ON CONFLICT DO NOTHING — no duplicate swaps (#287).
  • Failure: Duplicate trade rows.
  • Evidence: SQL count or API duplicate ids.
  • Cleanup: Fresh DB if corrupted.

INT-00-04 — Wallet ↔ cosmes patch signing

  • Actions: Run npx vitest run cosmesPatch127.test.ts in frontend-dapp.
  • Expected: Pass — fee override patches intact (#127).
  • Evidence: Vitest output.
  • Cleanup: N/A.

INT-00-05 — Vyntrex / integrator route parity

  • Actions: GET /api/v1/route/solve/best same params as Swap UI.
  • Expected: Same hop count as UI execution path for retail.
  • Failure: UI shows different path than /best.
  • Evidence: Two JSON dumps.
  • Cleanup: N/A.

INT-00-06 — QA laptop tunnel workflow

  • Preconditions: QA server remote.
  • Actions: Follow make qa-tunnel-help; scp .env.local; local npm run dev.
  • Expected: dApp talks to tunneled indexer/LCD.
  • Failure: CORS or wrong port.
  • Evidence: Tunnel script output; successful swap.
  • Cleanup: Close tunnel.

LR-00 — Launch Readiness (must be 100% PASS)

Gate: No launch sign-off until every item below passes on the target launch mode (pool-only v2 and/or hybrid). Hybrid-specific items apply only when hybrid launch is in scope — see RELEASE_READINESS_MATRIX (hybrid not ready until DEX-P1-003/005 closed).

LR-00-01 — Stack bootstrap INF-00-01 + Q1 INF-00-02

  • Pass criteria: Both PASS on clean QA or local fresh deploy.

LR-00-02 — Automated regression suite REG-00-01 through REG-00-10

  • Pass criteria: All make targets green on commit tagged for release.

LR-00-03 — On-chain smoke ONC-00-01 + single-hop + multihop tx

  • Pass criteria: smoke-pool-swap.sh pass; SW-00-01 + SW-00-02 PASS manually or via E2E.

LR-00-04 — Wallet matrix minimum

  • Pass criteria: WL-00-01 Keplr PASS; WL-00-03 simulated PASS; one WC mobile PASS (WL-00-05); Station LocalTerra limitation documented (#235) not blocking if Keplr path passes.

LR-00-05 — Core product flows

  • Pass criteria: SW-00-01, TR-00-02, LT-00-01, PL-00-02, FT-00-02, PF-00-01, CP-00-02 (or waived if create-pair out of launch scope — document waiver).

LR-00-06 — Indexer production invariants sample

  • Pass criteria: IDX-00-02, IDX-00-04, IDX-00-05, IDX-00-06 PASS; no raw LCD/SQL leaks.

LR-00-07 — Degraded mode honesty

  • Pass criteria: SW-00-06, TR-00-06, ERR-00-01 PASS; REG-00-07 outage E2E PASS.

LR-00-08 — Security UX gates

  • Pass criteria: SEC-00-04, SEC-00-05 PASS; PERF-00-03 no prod sourcemaps.

LR-00-09 — Accessibility minimum

  • Pass criteria: A11Y-00-01 PASS (no critical axe on swap/trade/limits).

LR-00-10 — Known blocker triage

  • Pass criteria: No open blocker:launch or blocker:v2 issues for pool-only launch; hybrid launch additionally requires no blocker:hybrid and PRODUCT sign-off on quote disclosure (DEX-P1-003).
  • Evidence: GitLab issue filter link; sign-off comment on this issue.

LR-00-11 — SDK 53 / LocalTerra (#292)

  • Pass criteria: If #292 merged, make reset-qa && make test-e2e PASS on new image digest; document terrad version in sign-off.

LR-00-12 — Slippage / route economics (#293)

  • Pass criteria: make verify-issue-293 PASS; retail >30% block confirmed (SW-00-04).

LR-00-13 — Documentation alignment

  • Pass criteria: make check-fee-discount-tier-docs PASS; operator confirms docs/runbooks/launch-checklist.md Phase 0–3 items applicable to staging are checked.

LR-00-14 — Cross-browser + mobile smoke

  • Pass criteria: XBR-00-03 Playwright PASS; RES-00-01 PASS.

LR-00-15 — Final sign-off comment template

Post comment on this issue with:

Build: <sha>
Environment: local | QA <host>
Launch mode: pool-only | hybrid
Wallet coverage: Keplr, Simulated, <others>
REG suite: PASS/FAIL
LR-00 checklist: <N>/15 PASS
Open blockers: <none | list>
Tester: @<username>
Date: YYYY-MM-DD

Execution Notes for Automation Engineers

  1. Prefer make targets over ad-hoc commands (docs/testing.md).
  2. Fresh volumes when seeing unknown variant LCD errors or address drift (#202, #120).
  3. E2E tx specs must run 1 worker — do not parallelize on-chain tests.
  4. Playwright workers: 5 for smoke per user rule / repo config.
  5. Indexer outage tests kill :3001 listeners — restart indexer after REG-00-07.
  6. Attach evidence to this issue or linked QA pass doc (docs/qa-templates/qa-test-pass.md).
  7. Pool-only vs hybrid: Tag each section result in sign-off; hybrid launch requires extra ONC-00-04, SW-00-08, LT ladder/book depth, and DEX-P1-003 disclosure checks.

## Automation Verification Engineer — Master Checklist **Role:** Automation Verification Engineer **Goal:** Executable, evidence-backed verification of the entire CL8Y DEX dApp and its LocalTerra / QA-server stack before launch. **Environments:** LocalTerra (`localterra`, LCD `:1317`, RPC `:26657`), QA server (`make start-qa` / SSH tunnel), indexer `:3001`, Vite `:5173` or `:3000`. **Out of scope:** Mainnet/testnet production deploys, treasury multisig ceremonies, formal smart-contract audits, infrastructure penetration tests, Prometheus/metrics (not implemented — #200). **References:** [`docs/qa-onboarding.md`](docs/qa-onboarding.md), [`docs/qa-invariants.md`](docs/qa-invariants.md), [`docs/testing.md`](docs/testing.md), [`QA_TEMPLATE.md`](QA_TEMPLATE.md), [`docs/runbooks/launch-checklist.md`](docs/runbooks/launch-checklist.md), [`docs/reviews/20260409T030009Z/RELEASE_READINESS_MATRIX.md`](docs/reviews/20260409T030009Z/RELEASE_READINESS_MATRIX.md), issue [#291](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/291) (CEX UX), [#292](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/292) (SDK 53), [#293](https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/issues/293) (slippage). **Item format:** Each row is a single verification scenario. Record **PASS/FAIL**, build SHA (`git rev-parse HEAD`), browser, wallet, and attach screenshots / tx hashes / API responses as noted. **Sign-off rule:** Section **LR-00 Launch Readiness** must be **100% PASS** with no open P0/P1 blockers before calling the dApp launch-ready. --- ## INF-00 — Environment & Stack Provisioning ### INF-00-01 — Fresh LocalTerra full stack bootstrap - **Preconditions:** Clean clone; Docker available; Node 24 via nvm; Rust stable. - **Actions:** `make setup-cloud-localterra` (or `make reset && make start && make wait-healthy && make build-optimized && make deploy-local && bash scripts/e2e-start-indexer.sh`). - **Expected:** `frontend-dapp/.env.local` and `indexer/.env` exist; `make has-localterra` exit 0; `curl -s http://127.0.0.1:3001/health` returns OK; Vite serves at `:5173`. - **Failure:** Missing env files, LCD timeout, indexer crash on migrate, deploy script stale-wasm error. - **Evidence:** Terminal log tail; `make status`; `.qa-deploy-stamp` contents; indexer startup log first 50 lines. - **Cleanup:** None (baseline stack). **Repeatability:** Use `QA_FRESH_VOLUMES=1 make start-qa` when prior volume suspected stale. ### INF-00-02 — Q1 deploy verification (schema + stamp) - **Preconditions:** Stack from INF-00-01. - **Actions:** `make qa-verify-deploy`. - **Expected:** Exit 0; LCD `is_paused` and `expired_limit_refund` queries succeed; stamp `git_sha` matches `git rev-parse HEAD`. - **Failure:** `unknown variant` on LCD queries (stale chain volume); stamp mismatch after `git pull` without redeploy. - **Evidence:** `scripts/qa/verify-deploy.sh` stdout; pair address from `.env.local`. - **Cleanup:** `make reset-qa` if schema probe fails. ### INF-00-03 — QA server idempotent restart - **Preconditions:** Prior successful QA deploy on same host. - **Actions:** `make stop-qa && make start-qa` (no fresh volumes). - **Expected:** Indexer reconnects; frontend env unchanged; `make qa-verify-deploy` still passes if HEAD unchanged. - **Failure:** Port conflicts on 3001/5432; indexer connects to wrong `FACTORY_ADDRESS`. - **Evidence:** `make status`; `lsof -i :3001`; indexer log `FACTORY_ADDRESS` line. - **Cleanup:** `make stop-qa`. ### INF-00-04 — Postgres role invariant (PG-1) - **Preconditions:** Compose Postgres up. - **Actions:** `make setup-indexer-postgres` or inspect `indexer/.env` `DATABASE_URL`; run `make test-indexer-integration` (subset: `cargo test --test security -- --test-threads=1`). - **Expected:** DB user `cl8y_legal` (not legacy `postgres` only); migrations apply. - **Failure:** `password authentication failed for user cl8y_legal`. - **Evidence:** `indexer/.env` redacted URL host/user; migration log. - **Cleanup:** N/A. ### INF-00-05 — Node 24 PATH for frontend dev - **Preconditions:** Cloud Agent or mixed PATH with `/exec-daemon/node` v22. - **Actions:** `make dev` (not bare `npm run dev`); open `http://127.0.0.1:5173` in Chrome. - **Expected:** Page loads without "Aw, Snap!"; `node -v` in dev script is v24.x per `.nvmrc`. - **Failure:** Chrome crash on load; wrong Node in Vite process. - **Evidence:** `ps aux | grep vite`; browser screenshot. - **Cleanup:** Kill stale Vite; restart via `make dev`. --- ## CFG-00 — Configuration & Environment Matrix ### CFG-00-01 — Local network env wiring - **Preconditions:** `deploy-local` completed. - **Actions:** Inspect `frontend-dapp/.env.local`: `VITE_NETWORK=local`, `VITE_LCD_URL`, `VITE_RPC_URL`, `VITE_FACTORY_ADDRESS`, `VITE_ROUTER_ADDRESS`, `VITE_INDEXER_URL=http://127.0.0.1:3001`. - **Expected:** All addresses `terra1…`; indexer URL matches running API. - **Failure:** Placeholder addresses; `VITE_INDEXER_URL` pointing at dead host. - **Evidence:** Redacted `.env.local` paste; browser Network tab `route/solve` host. - **Cleanup:** Re-run `make deploy-local`. ### CFG-00-02 — CORS localhost vs 127.0.0.1 - **Preconditions:** Indexer running; note `CORS_ORIGINS` in `indexer/.env`. - **Actions:** Open dApp at `http://localhost:5173` and separately at `http://127.0.0.1:5173`; trigger indexer fetch (Swap quote or Charts). - **Expected:** Both origins succeed (no CORS error in console). - **Failure:** `Access-Control-Allow-Origin` missing for one spelling (#131). - **Evidence:** Browser console CORS errors; `indexer/.env` `CORS_ORIGINS` line. - **Cleanup:** Add both origins; restart indexer. ### CFG-00-03 — Simulated wallet dev-only gate - **Preconditions:** `frontend-dapp/.env.development` with `VITE_DEV_MODE=true`, `VITE_DEV_MNEMONIC`. - **Actions:** Open wallet modal locally; run `npm run build` and confirm prod build rejects dev mnemonic (`vite.config.ts` guard). - **Expected:** Simulated Wallet visible in dev; absent in production build artifact. - **Failure:** Mnemonic in prod bundle. - **Evidence:** Wallet modal screenshot; build log error if mnemonic in prod env. - **Cleanup:** N/A. ### CFG-00-04 — Expert Mode / slippage settings persistence - **Preconditions:** Connected wallet on Swap. - **Actions:** Enable Expert Mode (if gated); set custom slippage; reload page. - **Expected:** Settings persist via `localStorage`; retail submit still blocks >30% slippage unless Expert on (#293). - **Failure:** Slippage resets silently; expert bypass without acknowledgement. - **Evidence:** `localStorage` keys screenshot; blocked submit UI for 35% slippage quote. - **Cleanup:** Clear site data to reset. --- ## WL-00 — Wallets & Authentication ### WL-00-01 — Keplr connect on LocalTerra (primary local wallet) - **Preconditions:** Keplr extension with LocalTerra network; stack up. - **Actions:** Connect Wallet → Keplr → approve; note header address chip. - **Expected:** `terra1…` truncated address; LUNC balance chip loads (#frontend.md). - **Failure:** Wrong chain; infinite spinner. - **Evidence:** Screenshot; Keplr network name. - **Cleanup:** Disconnect. ### WL-00-02 — Station on LocalTerra fee/signing limitation - **Preconditions:** Station extension on LocalTerra. - **Actions:** Attempt small swap with Station; compare with Keplr or Simulated Wallet on same amount. - **Expected:** Document outcome: Station may fail fee broadcast on LocalTerra (#235) — **do not count as dApp regression** if Keplr/simulated succeed. - **Failure (product):** Keplr/simulated also fail. - **Evidence:** Tx error message; wallet type in notes. - **Cleanup:** N/A. ### WL-00-03 — Simulated wallet E2E parity - **Preconditions:** `VITE_DEV_MODE=true`; dev mnemonic funded by deploy script. - **Actions:** Connect Simulated Wallet; execute swap on EMBER→CORAL (or deploy default pair). - **Expected:** Address `terra1x46rqay4d3cssq8gxxvqz8xt6nwlz4td20k38v`; tx confirms; balances update. - **Failure:** Insufficient funds; signing error. - **Evidence:** Tx hash; LCD `tx` query. - **Cleanup:** None. ### WL-00-04 — Extension not installed UX - **Preconditions:** Disable Keplr extension (or use clean profile). - **Actions:** Open wallet modal → Keplr row. - **Expected:** Dimmed row + **Install** link; no duplicate "Not installed" badge (#160). - **Failure:** Row shows Ready incorrectly. - **Evidence:** Screenshot. - **Cleanup:** Re-enable extension; refocus window to refresh (#139). ### WL-00-05 — WalletConnect session (Cosmostation mobile) - **Preconditions:** Mobile wallet app; desktop dApp on same network. - **Actions:** Connect via WalletConnect QR; approve session; disconnect from dApp. - **Expected:** QR → connected → clean disconnect without ghost session. - **Failure:** QR timeout without message; stuck "connecting". - **Evidence:** Screenshot of QR and connected state. - **Cleanup:** Disconnect both sides. ### WL-00-06 — Reject transaction recovery - **Preconditions:** Any connected extension wallet. - **Actions:** Start swap → reject in wallet popup. - **Expected:** UI returns to ready state; actionable "rejected" message; no stuck "pending" forever. - **Failure:** Button disabled permanently. - **Evidence:** Screenshot before/after. - **Cleanup:** Refresh if stuck. ### WL-00-07 — Leap wallet absent - **Preconditions:** Wallet modal open. - **Actions:** Search list for Leap. - **Expected:** Leap not listed (#159). - **Failure:** Leap row or broken install URL. - **Evidence:** Screenshot. - **Cleanup:** N/A. --- ## NAV-00 — Navigation, Routing & Global Shell ### NAV-00-01 — Primary route reachability - **Preconditions:** Stack up; no wallet required. - **Actions:** Visit `/`, `/trade`, `/limits`, `/pool`, `/create`, `/charts`, `/portfolio`, `/tiers`, `/protocol`; use header nav and mobile menu. - **Expected:** Each route renders without white screen; active nav highlight correct. - **Failure:** 404 blank; chunk load error without recovery. - **Evidence:** Screenshot per route; console errors. - **Cleanup:** N/A. ### NAV-00-02 — Deep link trade pair - **Preconditions:** Factory pair address from `.env.local` or pool list. - **Actions:** Navigate to `/trade/<pairAddr>` directly; reload. - **Expected:** Correct pair selected; chart and book load. - **Failure:** Fallback to wrong pair; crash on invalid address. - **Evidence:** URL bar; pair symbol displayed. - **Cleanup:** N/A. ### NAV-00-03 — Invalid route handling - **Preconditions:** None. - **Actions:** Visit `/nonexistent`, `/trade/not-a-terra-address`. - **Expected:** Redirect home or friendly empty state (#291 EH-5). - **Failure:** Uncaught exception white screen. - **Evidence:** Screenshot; console stack. - **Cleanup:** N/A. ### NAV-00-04 — Theme persistence - **Preconditions:** None. - **Actions:** Toggle light/dark/system; reload. - **Expected:** Theme persists (`localStorage`); no flash of wrong theme >1s. - **Failure:** Reset to default every reload. - **Evidence:** Screenshot both themes. - **Cleanup:** N/A. ### NAV-00-05 — `/my-portfolio` redirect - **Preconditions:** None. - **Actions:** Navigate to `/my-portfolio`. - **Expected:** Redirect to `/portfolio`. - **Failure:** 404. - **Evidence:** Network tab 302/redirect. - **Cleanup:** N/A. --- ## SW-00 — Swap (`/`) ### SW-00-01 — Direct pool swap (on-chain tx) - **Preconditions:** Simulated or Keplr wallet; pair EMBER/CORAL with liquidity. - **Actions:** Select tokens; enter `10` EMBER; review min received, price impact, route row; submit. - **Expected:** Single-hop route; tx succeeds; receive amount within slippage tolerance; success toast with explorer link. - **Failure:** Simulation error; tx fail on chain; amount mismatch > slippage. - **Evidence:** Tx hash; before/after CW20 balances via LCD; UI screenshot. - **Cleanup:** None. ### SW-00-02 — Multi-hop router swap - **Preconditions:** Wallet funded; token pair requiring ≥2 hops (e.g. token without direct pool). - **Actions:** Swap with indexer route showing ≥2 hops; submit via router path. - **Expected:** Route display shows ordered hops (#158 single Route row); router tx succeeds. - **Failure:** Duplicate/conflicting route lines; router ops mismatch submit payload. - **Evidence:** Network `route/solve` JSON; tx event `wasm` attributes. - **Cleanup:** None. ### SW-00-03 — Wrap native LUNC swap path - **Preconditions:** Wallet with uluna; Wrap-Mapper deployed. - **Actions:** Swap from native LUNC to CW20 (or reverse) using wrap/unwrap toggles. - **Expected:** Auto-wrap path clear; tx includes wrap mapper leg if needed. - **Failure:** Insufficient native for wrap gas; wrong denom in tx. - **Evidence:** Tx messages JSON; `wrap-swap.spec.ts` parity. - **Cleanup:** None. ### SW-00-04 — Slippage enrichment and retail guard (#293) - **Preconditions:** Indexer fresh deploy (`--fresh` if needed); pair with known arb asymmetry (EMBER→CORAL per `make verify-issue-293`). - **Actions:** Enter amount triggering >30% `slippage_percent` on route solve; attempt submit without Expert Mode. - **Expected:** Submit blocked; warning shows slippage % and spot comparison; Expert Mode allows with acknowledgement. - **Failure:** Submit allowed at 50% slippage retail; missing `slippage_percent` when assets clean. - **Evidence:** `GET /api/v1/route/solve?...` response fields; UI screenshot; `make verify-issue-293` output. - **Cleanup:** Fresh indexer DB if duplicate USTC-C assets. ### SW-00-05 — Max button gas reserve - **Preconditions:** Wallet with mixed native + CW20. - **Actions:** Click Max on native-denom swap. - **Expected:** Amount leaves LUNC reserve for gas (#291 OE-7). - **Failure:** Tx fails out of gas after Max. - **Evidence:** Input value vs wallet balance; tx result. - **Cleanup:** N/A. ### SW-00-06 — Swap during indexer outage - **Preconditions:** `E2E_INDEXER_OUTAGE=1` path or stop indexer; LCD up. - **Actions:** Load Swap; enter amount. - **Expected:** Market-data banner; LCD fallback quote or honest degradation; pool-only path may still work. - **Failure:** Infinite spinner; silent wrong quote. - **Evidence:** Banner screenshot; `swap-indexer-outage.spec.ts` parity. - **Cleanup:** Restart indexer. ### SW-00-07 — Fee tier discount on quote - **Preconditions:** Wallet registered on Fee Discount tier with CL8Y balance; tier active. - **Actions:** Compare quoted fee before/after registration on same pair. - **Expected:** Lower effective fee after tier; matches `fee-discount-quote-245` E2E. - **Failure:** Discount not applied in simulation or tx. - **Evidence:** LCD `hybrid_simulation` with `sender`; tier page status. - **Cleanup:** Deregister if test changed state. ### SW-00-08 — Hybrid swap disclosure (when hybrid enabled) - **Preconditions:** LocalTerra with limit book liquidity on pair. - **Actions:** Swap amount crossing pool+book; read hybrid disclosure / doc link. - **Expected:** Hybrid leg breakdown shown; matches `hybrid-swap.spec.ts`. - **Failure:** Pool-only UI while on-chain hybrid executed. - **Evidence:** Tx `pool_return_amount` / `book_return_amount` attrs; screenshot. - **Cleanup:** None. ### SW-00-09 — Pause banner blocks swap - **Preconditions:** Pair paused on-chain (governance test pair or local admin if available). - **Actions:** Attempt swap on paused pair. - **Expected:** Banner + disabled submit with clear copy (#87). - **Failure:** Tx broadcast then fail obscurely. - **Evidence:** LCD `is_paused`; UI screenshot. - **Cleanup:** Unpause pair. --- ## TR-00 — Trade Workspace (`/trade`) ### TR-00-01 — Initial load layout - **Preconditions:** Indexer + LCD up; default pair. - **Actions:** Open `/trade`; wait for chart, book, market panel. - **Expected:** No CLS >0.1 on pair header; skeletons resolve (`trade-page-initial-load.spec.ts`). - **Failure:** Overlapping panels; chart never mounts. - **Evidence:** Screenshot; Lighthouse CLS optional. - **Cleanup:** N/A. ### TR-00-02 — Market order panel execution - **Preconditions:** Connected wallet. - **Actions:** Market tab: enter size; submit market swap. - **Expected:** Same routing semantics as Swap page for execution path (#158). - **Failure:** Different route than Swap for identical inputs. - **Evidence:** Side-by-side route rows; tx hash. - **Cleanup:** None. ### TR-00-03 — Limit ticket place + view order - **Preconditions:** Wallet with offer token; pair with book. - **Actions:** Place limit from ticket; on success click **View order**. - **Expected:** Scroll/highlight to indexed placement row (#161). - **Failure:** Order not in list after 30s poll; poll error silent. - **Evidence:** Console for `[limit-place] indexer poll failed`; placement `order_id`. - **Cleanup:** Cancel order. ### TR-00-04 — Order book edit mode - **Preconditions:** Deep book data. - **Actions:** Enter book edit mode; modify level; cancel edit. - **Expected:** Edit affordances per #178; no orphan modal. - **Failure:** Edit persists without save. - **Evidence:** Screenshot; `trade-book-edit-178.spec.ts`. - **Cleanup:** Discard edits. ### TR-00-05 — Pair selector search CLS - **Preconditions:** Many pairs indexed. - **Actions:** Open pair dropdown; type filter; select pair. - **Expected:** No layout jump (`trade-pair-select-cls.spec.ts`). - **Failure:** List reflow shifts chart. - **Evidence:** Screen recording. - **Cleanup:** N/A. ### TR-00-06 — Trade page indexer outage - **Preconditions:** Indexer down; LCD up. - **Actions:** Load `/trade`. - **Expected:** Outage banner; chart/history degrade honestly (`trade-indexer-outage.spec.ts`). - **Failure:** Fake stale prices labeled live. - **Evidence:** Banner + last-updated timestamps. - **Cleanup:** Restart indexer. ### TR-00-07 — Responsive trade layout - **Preconditions:** Playwright mobile viewport or DevTools iPhone 14. - **Actions:** Complete market swap flow on mobile width. - **Expected:** Tap targets ≥44px; no horizontal scroll (`trade-page-responsive.spec.ts`). - **Failure:** Submit button off-screen. - **Evidence:** Screenshot 390px width. - **Cleanup:** N/A. --- ## LT-00 — Limit Orders (`/limits`) ### LT-00-01 — Single limit place + cancel (tx) - **Preconditions:** Funded wallet; pair with book. - **Actions:** Place single limit; wait indexer; cancel; confirm escrow returned. - **Expected:** Open order appears; cancel tx succeeds; row removed from active list (#135). - **Failure:** Cancelled id still in active placements API. - **Evidence:** Tx hashes; `GET .../limit-placements` before/after. - **Cleanup:** None. ### LT-00-02 — Batch limit placement - **Preconditions:** Wallet with sufficient offer token. - **Actions:** Place batch of 3 limits at distinct prices. - **Expected:** All 3 on-chain; indexer lists all; gas acceptable. - **Failure:** Partial batch without error surfacing. - **Evidence:** Tx events; API rows. - **Cleanup:** Cancel all. ### LT-00-03 — Ladder placement UI + tx (#295) - **Preconditions:** Ladder tab on `/limits`. - **Actions:** Clear rung count (stays empty); type `3`; type `25` rungs (inline max error); blur (clamps to 20); submit valid ladder. - **Expected:** Inline validation per `verify-issue-295-ladder-rung-ui.spec.ts`; ladder tx succeeds. - **Failure:** Empty field becomes 0; accepts 25 rungs. - **Evidence:** Screenshot validation states; `make verify-issue-295`. - **Cleanup:** Cancel ladder orders. ### LT-00-04 — Gas presets on limit place (#204) - **Preconditions:** Gas preset selector visible. - **Actions:** Select high gas preset; place limit; inspect tx gas wanted. - **Expected:** `max_adjust_steps` matches preset mapping (`verify-glab-204-limit-gas-presets.sh`). - **Failure:** Default gas on all presets. - **Evidence:** Tx simulation gas; script output. - **Cleanup:** Cancel order. ### LT-00-05 — Claim expired parked order - **Preconditions:** Expired parked limit on-chain (wait expiry or seed). - **Actions:** Claim refund from UI. - **Expected:** Escrow returned; lifecycle `refunded` in API (#142). - **Failure:** Claim during pair pause succeeds (should fail L6). - **Evidence:** LCD + API `lifecycle_status`. - **Cleanup:** N/A. ### LT-00-06 — Claim all expired batch - **Preconditions:** Multiple parked expired orders. - **Actions:** Use Claim All control. - **Expected:** Batch claim tx; all rows transition (`limit-orders-claim-all-tx.spec.ts`). - **Failure:** Partial claim without UI feedback. - **Evidence:** Tx hash; API diff. - **Cleanup:** N/A. ### LT-00-07 — Deep order book pagination - **Preconditions:** Book depth > one page. - **Actions:** Paginate limit-book UI; cross-check indexer `GET .../limit-book?cursor=`. - **Expected:** Consistent ordering; no duplicate levels (#267 gap handling). - **Failure:** Cursor loop; missing `pagination_gap` when walk incomplete. - **Evidence:** API JSON pages; screenshot. - **Cleanup:** N/A. ### LT-00-08 — Limits page indexer outage - **Preconditions:** Indexer stopped. - **Actions:** Open `/limits`. - **Expected:** Banner; LCD shallow book fallback if implemented. - **Failure:** Empty book with no explanation. - **Evidence:** `limits-indexer-outage.spec.ts` parity. - **Cleanup:** Restart indexer. --- ## PL-00 — Pool & Liquidity (`/pool`) ### PL-00-01 — Pool list search, sort, pagination - **Preconditions:** Indexer synced post-deploy (~23 pairs). - **Actions:** Search "EMBER"; sort by 24h volume desc; paginate. - **Expected:** Correct filtering; page bounds disable (#291 PL-1..PL-3). - **Failure:** Indexer-only pairs missing badge context. - **Evidence:** Screenshot; API `GET /api/v1/pairs?`. - **Cleanup:** N/A. ### PL-00-02 — Add liquidity (tx) - **Preconditions:** Wallet with both assets + LUNC gas. - **Actions:** Provide liquidity non-proportional ratio; confirm warning; submit. - **Expected:** Two-step allowance + provide; LP balance increases (`pool-tx.spec.ts`). - **Failure:** Tx fail; LP not credited. - **Evidence:** Tx hash; LP token balance LCD. - **Cleanup:** Withdraw liquidity. ### PL-00-03 — Remove liquidity (tx) - **Preconditions:** LP tokens from PL-00-02. - **Actions:** Withdraw 50% with 1% slippage preset. - **Expected:** Assets returned; pool reserves update. - **Failure:** Insufficient LP guard bypass. - **Evidence:** Tx hash; reserves before/after. - **Cleanup:** N/A. ### PL-00-04 — Wrap in provide liquidity - **Preconditions:** Native LUNC only for one side. - **Actions:** Provide with wrap toggle for native side. - **Expected:** Wrap + provide succeeds (`wrap-pool.spec.ts`). - **Failure:** Wrong denom in provide msg. - **Evidence:** Tx messages. - **Cleanup:** Withdraw if needed. ### PL-00-05 — Router-known vs indexer-only badge - **Preconditions:** Deploy includes unpaired/minimal pairs. - **Actions:** Toggle "Router-known (factory) only" filter. - **Expected:** Badges accurate (#291 PL-4). - **Failure:** Factory pair hidden incorrectly. - **Evidence:** Screenshot filter on/off. - **Cleanup:** N/A. --- ## CP-00 — Create Pair (`/create`) ### CP-00-01 — Validation gates - **Preconditions:** Wallet connected. - **Actions:** Enter invalid address; identical token A/B; non-whitelisted code ID token (ROGUE). - **Expected:** Inline errors; submit disabled (#291 CP-1..CP-3). - **Failure:** Tx broadcast for invalid pair. - **Evidence:** Screenshot errors. - **Cleanup:** N/A. ### CP-00-02 — Successful pair creation (tx) - **Preconditions:** Two whitelisted unused tokens; uluna creation fee. - **Actions:** Create pair; wait confirmation. - **Expected:** Factory `PairCreated` event; pair appears in list (`create-pair.spec.ts`). - **Failure:** Insufficient uluna without pre-check. - **Evidence:** Tx hash; factory query pair count. - **Cleanup:** Pair remains (acceptable on local). --- ## FT-00 — Fee Tiers (`/tiers`) ### FT-00-01 — Tier ladder display - **Preconditions:** Fee Discount deployed with 11 tiers. - **Actions:** Load `/tiers`; compare to `docs/reference/fee-discount-tiers.md`. - **Expected:** Holdings, discount %, effective fee match doc; `make check-fee-discount-tier-docs` passes. - **Failure:** Drift vs `tier_fixtures.rs`. - **Evidence:** Screenshot; make target output. - **Cleanup:** N/A. ### FT-00-02 — Register + deregister tier (tx) - **Preconditions:** Wallet with sufficient CL8Y for tier 1. - **Actions:** Register; verify swap fee reduction; deregister. - **Expected:** Status updates; on-chain tier cleared (`fee-tier-tx.spec.ts`). - **Failure:** Governance-only tier self-register enabled. - **Evidence:** Tx hashes; tier query. - **Cleanup:** Deregister. --- ## PF-00 — Portfolio & Trader Profiles ### PF-00-01 — Portfolio balances and positions - **Preconditions:** Wallet with LP + open limits + swap history. - **Actions:** Open `/portfolio` connected. - **Expected:** Balances match chain; positions table loads (#212); open limits (#217). - **Failure:** Stale balances after trade without refresh. - **Evidence:** Screenshot; compare LCD bank balances. - **Cleanup:** N/A. ### PF-00-02 — Wallet swap/limit history (#163) - **Preconditions:** Prior swaps and limits on connected address. - **Actions:** Open history sections; export CSV if available. - **Expected:** Rows match indexer `GET /api/v1/traders/{addr}/trades?format=csv`. - **Failure:** Empty history with indexed rows. - **Evidence:** CSV download; API response. - **Cleanup:** N/A. ### PF-00-03 — Public trader page - **Preconditions:** Known trader address (own or swarm bot). - **Actions:** Visit `/trader/<addr>`; reload; switch address in URL. - **Expected:** PnL color coding; shareable URL (#291 TR-1..TR-3). - **Failure:** Crash on invalid address. - **Evidence:** Screenshot; API 404 handling. - **Cleanup:** N/A. --- ## CH-00 — Charts (`/charts` & Trade chart) ### CH-00-01 — Candle intervals after seed-qa - **Preconditions:** `cd indexer && cargo run -- seed-qa`; indexer restarted. - **Actions:** Open Charts; pair with seeded data; switch 1m/1h/1d/1w. - **Expected:** Non-empty candles for seeded window (#113 empty = success not error). - **Failure:** Error state on empty []; chart crash. - **Evidence:** Screenshot per interval; API `GET .../candles?interval=`. - **Cleanup:** `cargo run -- seed-qa --clean` optional. ### CH-00-02 — Chart matches last trade - **Preconditions:** Recent swap on pair. - **Actions:** Compare chart last price to `GET .../trades?limit=1`. - **Expected:** Prices align within rounding. - **Failure:** >1% drift without stale indicator. - **Evidence:** Screenshot + API JSON. - **Cleanup:** N/A. ### CH-00-03 — Charts indexer outage - **Preconditions:** Indexer down. - **Actions:** Load `/charts`. - **Expected:** Outage banner; no uncaught exception (`charts-indexer-outage.spec.ts`). - **Failure:** White screen. - **Evidence:** Screenshot. - **Cleanup:** Restart indexer. ### CH-00-04 — Price chart smoke (indicators) - **Preconditions:** Seeded or live data. - **Actions:** Enable MA/RSI on trade chart if exposed. - **Expected:** Indicators render (`price-chart-smoke.spec.ts`, `test-frontend-charts`). - **Failure:** NaN lines; autoscale break (#229). - **Evidence:** Screenshot. - **Cleanup:** N/A. --- ## PR-00 — Protocol & Oracle (`/protocol`) ### PR-00-01 — Oracle price display - **Preconditions:** Indexer oracle feed running. - **Actions:** Load `/protocol`; note USTC/USD price, source, fetched-at. - **Expected:** Values match `GET /api/v1/oracle/price`. - **Failure:** Stale timestamp without warning. - **Evidence:** Screenshot; API response. - **Cleanup:** N/A. ### PR-00-02 — Hook events feed - **Preconditions:** Pairs with hooks deployed (if any on local). - **Actions:** Filter hook events table by contract. - **Expected:** Rows with tx links; empty state if none. - **Failure:** 500 surfaced raw to user. - **Evidence:** API `GET /api/v1/hooks`. - **Cleanup:** N/A. --- ## IDX-00 — Indexer API & Sync ### IDX-00-01 — Health and Swagger - **Preconditions:** Indexer running. - **Actions:** `GET /health`; open `/swagger-ui`. - **Expected:** Health OK; documented routes load. - **Failure:** 404 swagger; health DB false. - **Evidence:** curl output; screenshot. - **Cleanup:** N/A. ### IDX-00-02 — Route solve GET global best execution - **Preconditions:** Router address in indexer env. - **Actions:** `GET /api/v1/route/solve?token_in=...&token_out=...&amount_in=1000000` with hybrid-capable pair. - **Expected:** `estimated_amount_out`, `solver_version`, `paths_considered`; 502 not raw LCD leak (#239). - **Failure:** Internal server error with SQL text; LCD stack in body. - **Evidence:** Redacted JSON response; indexer log trace. - **Cleanup:** N/A. ### IDX-00-03 — Route solve POST hybrid_by_hop length validation - **Preconditions:** Indexer up. - **Actions:** POST with `hybrid_by_hop` length ≠ hop count. - **Expected:** HTTP 400 generic message. - **Failure:** 500 panic. - **Evidence:** curl -d JSON; response body. - **Cleanup:** N/A. ### IDX-00-04 — Security caps (limit injection) - **Preconditions:** Indexer up. - **Actions:** `GET /api/v1/pairs/.../candles?interval=1m';DROP TABLE--` and `limit=-1`. - **Expected:** 400 bad interval; limit clamps to 1 not 500 (#243). - **Failure:** 500; negative LIMIT. - **Evidence:** `make test-indexer-integration` security tests log. - **Cleanup:** N/A. ### IDX-00-05 — Indexer sync after swap - **Preconditions:** Note latest indexed height. - **Actions:** Execute swap; wait ≤30s. - **Expected:** New row in `GET .../trades`; candle bucket updates. - **Failure:** No sync after 2 min while chain progresses. - **Evidence:** Trade API row tx_hash; indexer log block height. - **Cleanup:** N/A. ### IDX-00-06 — CG/CMC compliance shapes - **Preconditions:** Indexer up. - **Actions:** `GET /cg/orderbook?ticker_id=...`; `GET /cmc/orderbook/{pair}`. - **Expected:** CG object; CMC array of one book (#223); timestamps numeric ms/s (#222). - **Failure:** Wrong JSON shape. - **Evidence:** curl JSON snippets. - **Cleanup:** N/A. ### IDX-00-07 — Hybrid volume L10 reconciliation - **Preconditions:** Hybrid swap indexed. - **Actions:** Compare swap row `return_amount` to `pool_leg_volume` + `book_leg_volume`. - **Expected:** pool + book = return on ask side (#216). - **Failure:** Double-count in ticker volume. - **Evidence:** API trade row; `api_integrator_hybrid_volume` test reference. - **Cleanup:** N/A. ### IDX-00-08 — Lifecycle emitter scoping (#285) - **Preconditions:** LocalTerra with test harness or `make verify-issue-285`. - **Actions:** Run verification script. - **Expected:** Forged `contract_address` does not attribute lifecycle to victim pair. - **Failure:** Victim pair shows attacker's fill. - **Evidence:** `make verify-issue-285` output. - **Cleanup:** N/A. --- ## ONC-00 — On-Chain Contracts (functional, not audit) ### ONC-00-01 — Smoke pool swap script - **Preconditions:** Deploy complete. - **Actions:** `bash scripts/smoke-pool-swap.sh`. - **Expected:** LCD pool query OK; simulation succeeds pool-only. - **Failure:** Non-zero exit. - **Evidence:** Script stdout. - **Cleanup:** N/A. ### ONC-00-02 — Factory pause semantics - **Preconditions:** Ability to pause pair via factory (local gov key). - **Actions:** Pause pair; attempt swap and limit place; unpause. - **Expected:** Swap/place blocked; cancel refund path works (#87). - **Failure:** Swap succeeds while paused. - **Evidence:** LCD queries; tx errors. - **Cleanup:** Unpause. ### ONC-00-03 — Fee discount trusted router - **Preconditions:** Router deployed. - **Actions:** Query `is_trusted_router` on Fee Discount contract. - **Expected:** `true` for production router address. - **Failure:** false while UI assumes router discounts. - **Evidence:** LCD query JSON. - **Cleanup:** N/A. ### ONC-00-04 — Hybrid simulation vs execution (L8) - **Preconditions:** Book liquidity exists. - **Actions:** `hybrid_simulation` then matching `hybrid` execute same params. - **Expected:** Output within documented tolerance (`limit_order_tests.rs` L8). - **Failure:** >1% drift sim vs exec. - **Evidence:** LCD sim JSON; tx result attributes. - **Cleanup:** N/A. --- ## ERR-00 — Error Recovery & Degraded Modes ### ERR-00-01 — LCD outage during quote - **Preconditions:** Stop LocalTerra container briefly or block LCD port. - **Actions:** Request swap quote. - **Expected:** User-visible LCD error; retry affordance; no white screen. - **Failure:** Cached fake quote. - **Evidence:** Screenshot; network failed requests. - **Cleanup:** `make start`. ### ERR-00-02 — ErrorBoundary recovery - **Preconditions:** DevTools open (optional forced error route if exists). - **Actions:** Trigger render error boundary (known test hook or invalid props via chaos). - **Expected:** Recovery UI with reload action (#291 EH-4). - **Failure:** Blank white page. - **Evidence:** Screenshot. - **Cleanup:** Reload. ### ERR-00-03 — Tx broadcast timeout - **Preconditions:** Simulate slow RPC (throttle) if possible. - **Actions:** Submit swap; wait past timeout threshold. - **Expected:** Actionable timeout message; user can retry without refresh. - **Failure:** Infinite pending. - **Evidence:** UI state after 2 min; console logs. - **Cleanup:** N/A. ### ERR-00-04 — Insufficient balance preflight - **Preconditions:** Wallet with 1 token only. - **Actions:** Attempt swap exceeding balance. - **Expected:** Blocked before wallet popup (#291 EH-2). - **Failure:** Wallet opens then fails obscurely. - **Evidence:** Screenshot disabled button/tooltip. - **Cleanup:** N/A. --- ## CON-00 — Concurrency & Load (local/QA only) ### CON-00-01 — Trading swarm stress - **Preconditions:** `make swarm-local` or `make swarm-launch` prerequisites met. - **Actions:** Run swarm 5–10 min; use dApp concurrently on `/trade`. - **Expected:** UI remains responsive; indexer rate limits 429 not crash. - **Failure:** OOM indexer; dApp freeze. - **Evidence:** `make status`; indexer memory; screenshot UI still interactive. - **Cleanup:** Stop swarm. ### CON-00-02 — Parallel Playwright e2e-tx isolation - **Preconditions:** LocalTerra up. - **Actions:** `make test-e2e-tx` (1 worker by design). - **Expected:** All tx specs pass serialized without nonce collisions. - **Failure:** Account sequence mismatch failures. - **Evidence:** Playwright report. - **Cleanup:** Fresh deploy if sequence corrupted. ### CON-00-03 — Duplicate tab quote consistency - **Preconditions:** Two tabs on Swap same pair. - **Actions:** Enter amount in tab A; switch tab B same amount. - **Expected:** Quotes match within refresh window. - **Failure:** Divergent routes without amount change. - **Evidence:** Side-by-side screenshots. - **Cleanup:** Close tabs. --- ## XBR-00 — Cross-Browser (local) ### XBR-00-01 — Chrome desktop (primary) - **Preconditions:** Stack up. - **Actions:** Execute SW-00-01 in Chrome latest. - **Expected:** Pass. - **Failure:** Any regression vs baseline. - **Evidence:** As SW-00-01. - **Cleanup:** N/A. ### XBR-00-02 — Firefox desktop swap smoke - **Preconditions:** Firefox installed. - **Actions:** Connect Keplr FF or simulated; one swap. - **Expected:** Functional parity for core flow. - **Failure:** Wallet connect broken entirely. - **Evidence:** Screenshot; tx hash or block reason. - **Cleanup:** N/A. ### XBR-00-03 — Playwright Chromium automated suite - **Preconditions:** Full stack. - **Actions:** `CI=1 make test-e2e` (5 workers smoke). - **Expected:** All non-skipped specs green. - **Failure:** Any failure — attach HTML report. - **Evidence:** `frontend-dapp/playwright-report/`. - **Cleanup:** N/A. --- ## RES-00 — Responsive Layout ### RES-00-01 — Mobile navigation stack - **Preconditions:** 390×844 viewport. - **Actions:** Navigate all primary routes via mobile menu. - **Expected:** No trapped views; back works (#291 ME-2). - **Failure:** Modal overflow off-screen. - **Evidence:** Screenshots each route. - **Cleanup:** N/A. ### RES-00-02 — Tablet trade layout - **Preconditions:** 768px width. - **Actions:** Place limit from `/trade`. - **Expected:** Form usable without horizontal scroll. - **Failure:** Overlapping chart on ticket. - **Evidence:** Screenshot. - **Cleanup:** Cancel limit. --- ## A11Y-00 — Accessibility ### A11Y-00-01 — Critical routes axe scan - **Preconditions:** Stack up. - **Actions:** Run `e2e/a11y-critical-routes.spec.ts` or axe DevTools on `/`, `/trade`, `/limits`. - **Expected:** No critical violations; focus visible (#144). - **Failure:** Missing focus ring on swap submit. - **Evidence:** axe report JSON. - **Cleanup:** N/A. ### A11Y-00-02 — Keyboard-only swap - **Preconditions:** Desktop; no mouse. - **Actions:** Tab to token selector, amount, submit; activate via Enter/Space. - **Expected:** Full flow completable (#291 AX-1). - **Failure:** Focus trap escape impossible. - **Evidence:** Screen recording. - **Cleanup:** N/A. ### A11Y-00-03 — Modal focus trap - **Preconditions:** Open wallet modal. - **Actions:** Tab through; Escape close. - **Expected:** Focus trapped inside; restored to trigger on close (#291 AX-2). - **Failure:** Focus lost to background. - **Evidence:** Document.activeElement notes. - **Cleanup:** N/A. --- ## PERF-00 — Performance (local/QA) ### PERF-00-01 — Quote latency p95 - **Preconditions:** Normal load; indexer warm. - **Actions:** DevTools Performance; 20 quote requests typing amount on Swap. - **Expected:** p95 < 1s for indexer route solve (#291 PR-3). - **Failure:** >3s consistent. - **Evidence:** HAR or Performance trace. - **Cleanup:** N/A. ### PERF-00-02 — Trade page memory 30 min - **Preconditions:** `/trade` open. - **Actions:** Leave 30 min with swarm optional; sample heap. - **Expected:** No runaway growth (#291 PR-4). - **Failure:** >200MB growth without trades. - **Evidence:** Chrome heap snapshot diff. - **Cleanup:** Close tab. ### PERF-00-03 — Production bundle no sourcemaps - **Preconditions:** `npm run build` in frontend-dapp. - **Expected:** No `.js.map` in `dist/` for production mode (#117). - **Failure:** Maps published. - **Evidence:** `find dist -name '*.map'`. - **Cleanup:** N/A. --- ## SEC-00 — Application Security Behavior (not formal audit) ### SEC-00-01 — Blacklist compliance probe - **Preconditions:** Indexer `blacklist-check` endpoint. - **Actions:** `GET /api/v1/compliance/blacklist-check?address=...` for known clean and test flagged addresses per docs. - **Expected:** JSON status; dApp surfaces trading block if flagged. - **Failure:** Swap allowed for flagged address without warning. - **Evidence:** API response; UI screenshot. - **Cleanup:** N/A. ### SEC-00-02 — Rate limit 429 on abuse - **Preconditions:** `RATE_LIMIT_RPS` enabled (default 60). - **Actions:** Burst >100 requests/sec to `/api/v1/route/solve` from single IP. - **Expected:** 429 responses; process stable (#278). - **Failure:** OOM or 500 storm. - **Evidence:** curl loop status codes. - **Cleanup:** Wait cooldown. ### SEC-00-03 — CORS rejection - **Preconditions:** Indexer with strict `CORS_ORIGINS`. - **Actions:** `curl -H "Origin: https://evil.example" /api/v1/pairs`. - **Expected:** No `Access-Control-Allow-Origin` for evil origin. - **Failure:** `*` in production config. - **Evidence:** Response headers. - **Cleanup:** N/A. ### SEC-00-04 — Risk disclosure / legal footer (#138) - **Preconditions:** Swap page loaded. - **Actions:** Verify legal footer links and risk acknowledgement on first swap. - **Expected:** Present per `docs/frontend.md` risk surfacing; E2E #138 paths pass. - **Failure:** Missing disclosure. - **Evidence:** Screenshot; `make test-e2e` filter *138* if exists. - **Cleanup:** N/A. ### SEC-00-05 — Retail slippage hard block - **Preconditions:** Quote >30% slippage (#293). - **Actions:** Attempt submit without Expert Mode. - **Expected:** Blocked. - **Failure:** Funds at risk via unguarded submit. - **Evidence:** As SW-00-04. - **Cleanup:** N/A. --- ## OBS-00 — Observability & Evidence Collection ### OBS-00-01 — Indexer structured logs on block lag - **Preconditions:** Indexer running. - **Actions:** Inspect logs during catch-up after restart. - **Expected:** Block height progress; warnings on slow blocks (#200 scope: logs only). - **Failure:** Silent stall with no log. - **Evidence:** Log excerpt with heights. - **Cleanup:** N/A. ### OBS-00-02 — Tx explorer links - **Preconditions:** Successful swap. - **Actions:** Click tx link in success toast. - **Expected:** Opens correct explorer URL for `localterra` (or configured explorer). - **Failure:** 404 explorer page. - **Evidence:** URL bar. - **Cleanup:** N/A. ### OBS-00-03 — Terra broadcast confirming link - **Preconditions:** Pending tx. - **Actions:** Observe confirming state link (`terra-broadcast-confirming-link-tx.spec.ts`). - **Expected:** Link becomes clickable when hash known. - **Failure:** Dead link during broadcast. - **Evidence:** Screenshot pending state. - **Cleanup:** N/A. --- ## REG-00 — Automated Regression Gates ### REG-00-01 — Contract unit tests - **Actions:** `make test-contracts`. - **Expected:** All pass. - **Evidence:** CI log or local output. - **Cleanup:** N/A. ### REG-00-02 — Frontend unit tests - **Actions:** `make test-frontend`. - **Expected:** 600+ tests pass Node 24. - **Evidence:** Vitest summary. - **Cleanup:** N/A. ### REG-00-03 — Indexer lib tests - **Actions:** `cd indexer && cargo test --lib`. - **Expected:** Pass without Postgres. - **Evidence:** cargo output. - **Cleanup:** N/A. ### REG-00-04 — Indexer integration tests - **Preconditions:** `make setup-indexer-postgres`. - **Actions:** `make test-indexer-integration`. - **Expected:** Serialized pass. - **Evidence:** Test summary. - **Cleanup:** N/A. ### REG-00-05 — Charts integration - **Actions:** `make test-charts-integration`. - **Expected:** HTTP + ChartsPage integration pass. - **Evidence:** Output log. - **Cleanup:** N/A. ### REG-00-06 — E2E strict on-chain - **Preconditions:** INF-00-01 stack. - **Actions:** `CI=1 make test-e2e` and `make test-e2e-tx`. - **Expected:** Green. - **Evidence:** Playwright report paths. - **Cleanup:** N/A. ### REG-00-07 — E2E indexer outage project - **Actions:** `make test-e2e-indexer-outage`. - **Expected:** Green with OUTAGE_E2E_INDEXER_URL dead port. - **Evidence:** Script log. - **Cleanup:** Restart indexer per `docs/testing.md`. ### REG-00-08 — Issue-specific verifiers - **Actions:** `make verify-issue-285 && make verify-issue-293 && make verify-issue-295 && make verify-issue-324` (as applicable). - **Expected:** All exit 0 on current stack. - **Evidence:** Script stdout. - **Cleanup:** N/A. ### REG-00-09 — Fee tier doc drift - **Actions:** `make check-fee-discount-tier-docs`. - **Expected:** Exit 0. - **Evidence:** Output. - **Cleanup:** N/A. ### REG-00-10 — Lint gates - **Actions:** `make lint-contracts && make lint-frontend`. - **Expected:** Exit 0. - **Evidence:** Output. - **Cleanup:** N/A. --- ## EDGE-00 — Edge Cases & Boundary Conditions ### EDGE-00-01 — Zero amount swap - **Actions:** Enter 0; click swap. - **Expected:** Submit disabled ("Enter Amount"). - **Failure:** Wallet popup opens. - **Evidence:** Screenshot. - **Cleanup:** N/A. ### EDGE-00-02 — Decimal precision dust - **Actions:** Swap 0.000001 smallest unit. - **Expected:** No scientific notation leak; simulation or min amount error (#291 OE-9). - **Failure:** `1e-18` displayed. - **Evidence:** Screenshot. - **Cleanup:** N/A. ### EDGE-00-03 — Non-whitelisted token pair swap attempt - **Preconditions:** ROGUE/BOGUS tokens. - **Actions:** Attempt route through non-whitelisted pair. - **Expected:** Graceful no-route or factory rejection. - **Failure:** UI offers impossible tx. - **Evidence:** Route solve 404/400. - **Cleanup:** N/A. ### EDGE-00-04 — Expired limit during match - **Preconditions:** Limit near expiry + matching taker flow. - **Actions:** Execute taker swap as limit expires. - **Expected:** Contract unlinks per `limit-orders.md`; no maker double-pay. - **Failure:** Stuck escrow. - **Evidence:** On-chain events; API lifecycle. - **Cleanup:** Claim if parked. ### EDGE-00-05 — Multi-swap same tx indexing (#287) - **Preconditions:** Router tx with 2 swaps same pair if scenario exists. - **Actions:** Verify indexer creates distinct `swap_index` rows. - **Expected:** No dedup collision. - **Failure:** Missing second swap in API. - **Evidence:** trades API rows sharing tx_hash. - **Cleanup:** N/A. ### EDGE-00-06 — Chunk load failure recovery - **Preconditions:** Throttle network; navigate to lazy route. - **Actions:** Trigger chunk load error. - **Expected:** Retry/reload prompt (#291 PR-5). - **Failure:** Permanent blank. - **Evidence:** Screenshot. - **Cleanup:** Hard reload. --- ## INT-00 — Integration Boundaries ### INT-00-01 — Frontend ↔ indexer contract - **Actions:** Compare `frontend-dapp/src/services/indexer/client.ts` types to live `GET /api/v1/pairs` schema. - **Expected:** No Zod/runtime parse errors in console on Pool page. - **Failure:** Type drift causes silent drop. - **Evidence:** Console errors. - **Cleanup:** N/A. ### INT-00-02 — Frontend ↔ LCD contract - **Actions:** Pool reserves on UI vs LCD `pool` query. - **Expected:** Match within rounding. - **Failure:** 10%+ reserve drift while LCD healthy. - **Evidence:** LCD JSON + UI screenshot. - **Cleanup:** N/A. ### INT-00-03 — Indexer ↔ chain reorg safety (replay) - **Actions:** Restart indexer; re-index same blocks. - **Expected:** `ON CONFLICT DO NOTHING` — no duplicate swaps (#287). - **Failure:** Duplicate trade rows. - **Evidence:** SQL count or API duplicate ids. - **Cleanup:** Fresh DB if corrupted. ### INT-00-04 — Wallet ↔ cosmes patch signing - **Actions:** Run `npx vitest run cosmesPatch127.test.ts` in frontend-dapp. - **Expected:** Pass — fee override patches intact (#127). - **Evidence:** Vitest output. - **Cleanup:** N/A. ### INT-00-05 — Vyntrex / integrator route parity - **Actions:** `GET /api/v1/route/solve/best` same params as Swap UI. - **Expected:** Same hop count as UI execution path for retail. - **Failure:** UI shows different path than `/best`. - **Evidence:** Two JSON dumps. - **Cleanup:** N/A. ### INT-00-06 — QA laptop tunnel workflow - **Preconditions:** QA server remote. - **Actions:** Follow `make qa-tunnel-help`; scp `.env.local`; local `npm run dev`. - **Expected:** dApp talks to tunneled indexer/LCD. - **Failure:** CORS or wrong port. - **Evidence:** Tunnel script output; successful swap. - **Cleanup:** Close tunnel. --- ## LR-00 — Launch Readiness (must be 100% PASS) > **Gate:** No launch sign-off until every item below passes on the target launch mode (pool-only v2 and/or hybrid). Hybrid-specific items apply only when hybrid launch is in scope — see RELEASE_READINESS_MATRIX (hybrid **not ready** until DEX-P1-003/005 closed). ### LR-00-01 — Stack bootstrap INF-00-01 + Q1 INF-00-02 - **Pass criteria:** Both PASS on clean QA or local fresh deploy. ### LR-00-02 — Automated regression suite REG-00-01 through REG-00-10 - **Pass criteria:** All make targets green on commit tagged for release. ### LR-00-03 — On-chain smoke ONC-00-01 + single-hop + multihop tx - **Pass criteria:** `smoke-pool-swap.sh` pass; SW-00-01 + SW-00-02 PASS manually or via E2E. ### LR-00-04 — Wallet matrix minimum - **Pass criteria:** WL-00-01 Keplr PASS; WL-00-03 simulated PASS; one WC mobile PASS (WL-00-05); Station LocalTerra limitation documented (#235) not blocking if Keplr path passes. ### LR-00-05 — Core product flows - **Pass criteria:** SW-00-01, TR-00-02, LT-00-01, PL-00-02, FT-00-02, PF-00-01, CP-00-02 (or waived if create-pair out of launch scope — document waiver). ### LR-00-06 — Indexer production invariants sample - **Pass criteria:** IDX-00-02, IDX-00-04, IDX-00-05, IDX-00-06 PASS; no raw LCD/SQL leaks. ### LR-00-07 — Degraded mode honesty - **Pass criteria:** SW-00-06, TR-00-06, ERR-00-01 PASS; REG-00-07 outage E2E PASS. ### LR-00-08 — Security UX gates - **Pass criteria:** SEC-00-04, SEC-00-05 PASS; PERF-00-03 no prod sourcemaps. ### LR-00-09 — Accessibility minimum - **Pass criteria:** A11Y-00-01 PASS (no critical axe on swap/trade/limits). ### LR-00-10 — Known blocker triage - **Pass criteria:** No open `blocker:launch` or `blocker:v2` issues for pool-only launch; hybrid launch additionally requires no `blocker:hybrid` and PRODUCT sign-off on quote disclosure (DEX-P1-003). - **Evidence:** GitLab issue filter link; sign-off comment on this issue. ### LR-00-11 — SDK 53 / LocalTerra (#292) - **Pass criteria:** If #292 merged, `make reset-qa && make test-e2e` PASS on new image digest; document terrad version in sign-off. ### LR-00-12 — Slippage / route economics (#293) - **Pass criteria:** `make verify-issue-293` PASS; retail >30% block confirmed (SW-00-04). ### LR-00-13 — Documentation alignment - **Pass criteria:** `make check-fee-discount-tier-docs` PASS; operator confirms `docs/runbooks/launch-checklist.md` Phase 0–3 items applicable to staging are checked. ### LR-00-14 — Cross-browser + mobile smoke - **Pass criteria:** XBR-00-03 Playwright PASS; RES-00-01 PASS. ### LR-00-15 — Final sign-off comment template Post comment on this issue with: ``` Build: <sha> Environment: local | QA <host> Launch mode: pool-only | hybrid Wallet coverage: Keplr, Simulated, <others> REG suite: PASS/FAIL LR-00 checklist: <N>/15 PASS Open blockers: <none | list> Tester: @<username> Date: YYYY-MM-DD ``` --- ## Execution Notes for Automation Engineers 1. **Prefer make targets** over ad-hoc commands (`docs/testing.md`). 2. **Fresh volumes** when seeing `unknown variant` LCD errors or address drift (#202, #120). 3. **E2E tx specs** must run **1 worker** — do not parallelize on-chain tests. 4. **Playwright workers:** 5 for smoke per user rule / repo config. 5. **Indexer outage tests** kill :3001 listeners — restart indexer after REG-00-07. 6. **Attach evidence** to this issue or linked QA pass doc (`docs/qa-templates/qa-test-pass.md`). 7. **Pool-only vs hybrid:** Tag each section result in sign-off; hybrid launch requires extra ONC-00-04, SW-00-08, LT ladder/book depth, and DEX-P1-003 disclosure checks. ---
PlasticDigits commented 2026-06-07 12:14:11 +00:00 (Migrated from gitlab.com)

assigned to @Brouie

assigned to @Brouie
ghost1 commented 2026-06-07 13:12:53 +00:00 (Migrated from gitlab.com)

mentioned in commit 561d8482e5

mentioned in commit 561d8482e5af9e8946ac5fbeedec8ecd267d9177
ghost1 commented 2026-06-07 13:12:53 +00:00 (Migrated from gitlab.com)

mentioned in commit 20826eaf42

mentioned in commit 20826eaf42072fb2aacd7317ef043d7c38e8f485
PlasticDigits commented 2026-06-07 13:13:18 +00:00 (Migrated from gitlab.com)

Verification pass — Automation Verification Engineer master checklist (#337)

Build: 20826ea (docs MR branch) / stack at 038a457
Environment: Cloud Agent VM, LocalTerra Docker, indexer :3001, Vite :5173
Issue: https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/337

Outcome

Opened MR with doc cross-links and Cloud Agent E2E guardrail. Issue stays open until MR merges.

Checklist document integrity — PASS

  • All 6 header reference docs exist (qa-onboarding, qa-invariants, testing, QA_TEMPLATE, launch-checklist, RELEASE_READINESS_MATRIX)
  • All 25 make targets cited in the issue body are defined in the root Makefile
  • Referenced QA scripts exist under scripts/qa/

Sample execution (automated)

Section Item Result How verified
INF INF-00-01 bootstrap PASS make setup-cloud-localterra
INF INF-00-02 Q1 PASS make qa-verify-deploy
INF INF-00-04 PG-1 PASS cl8y_legal + make test-indexer-integration
REG REG-00-01..04, 09, 10 PASS contracts, frontend, indexer lib/integration, fee docs, lint
REG REG-00-05 charts FAIL make test-charts-integration — no host psql
REG REG-00-06 E2E PARTIAL sg docker -c 'CI=1 make test-e2e' — 101/105 smoke pass
REG REG-00-07 outage FAIL indexer tmux session blocked stop
REG REG-00-08 verifiers PARTIAL #295/#324 pass; #293/#285 fail (fresh-volume path documented in checklist)
ONC ONC-00-01 PASS scripts/smoke-pool-swap.sh with deploy stamp pair
LR LR-00 full sign-off NOT RUN Requires human wallet matrix + 100% REG — see MR for gap list

Manual sections (Keplr, WalletConnect, mobile nav, 30-min perf, etc.) remain for human QA using this checklist as the source of truth.

## Verification pass — Automation Verification Engineer master checklist (#337) **Build:** `20826ea` (docs MR branch) / stack at `038a457` **Environment:** Cloud Agent VM, LocalTerra Docker, indexer `:3001`, Vite `:5173` **Issue:** https://gitlab.com/PlasticDigits/cl8y-dex-terraclassic/-/work_items/337 ### Outcome Opened **MR** with doc cross-links and Cloud Agent E2E guardrail. Issue stays **open** until MR merges. ### Checklist document integrity — **PASS** - All 6 header reference docs exist (`qa-onboarding`, `qa-invariants`, `testing`, `QA_TEMPLATE`, `launch-checklist`, `RELEASE_READINESS_MATRIX`) - All 25 `make` targets cited in the issue body are defined in the root `Makefile` - Referenced QA scripts exist under `scripts/qa/` ### Sample execution (automated) | Section | Item | Result | How verified | |---------|------|--------|--------------| | INF | INF-00-01 bootstrap | **PASS** | `make setup-cloud-localterra` | | INF | INF-00-02 Q1 | **PASS** | `make qa-verify-deploy` | | INF | INF-00-04 PG-1 | **PASS** | `cl8y_legal` + `make test-indexer-integration` | | REG | REG-00-01..04, 09, 10 | **PASS** | contracts, frontend, indexer lib/integration, fee docs, lint | | REG | REG-00-05 charts | **FAIL** | `make test-charts-integration` — no host `psql` | | REG | REG-00-06 E2E | **PARTIAL** | `sg docker -c 'CI=1 make test-e2e'` — 101/105 smoke pass | | REG | REG-00-07 outage | **FAIL** | indexer tmux session blocked stop | | REG | REG-00-08 verifiers | **PARTIAL** | #295/#324 pass; #293/#285 fail (fresh-volume path documented in checklist) | | ONC | ONC-00-01 | **PASS** | `scripts/smoke-pool-swap.sh` with deploy stamp pair | | LR | LR-00 full sign-off | **NOT RUN** | Requires human wallet matrix + 100% REG — see MR for gap list | Manual sections (Keplr, WalletConnect, mobile nav, 30-min perf, etc.) remain for human QA using this checklist as the source of truth.
PlasticDigits commented 2026-06-07 13:13:27 +00:00 (Migrated from gitlab.com)

mentioned in merge request !833

mentioned in merge request !833
Brouie commented 2026-06-08 00:20:36 +00:00 (Migrated from gitlab.com)

mentioned in merge request !834

mentioned in merge request !834
Brouie commented 2026-06-08 00:20:37 +00:00 (Migrated from gitlab.com)

mentioned in merge request !835

mentioned in merge request !835
Brouie commented 2026-06-08 00:32:38 +00:00 (Migrated from gitlab.com)

Worked the whole no-browser half of this checklist on a fresh make reset-qa at 038a457 (clean genesis: 25 pairs / 60 swaps / 14 assets, USTC-C unique so the #293 enrichment path is live). Posting this as progress, not a sign-off — it's the contract + indexer + source layer. The browser/UI matrix (wallets, nav, swap/trade/limits/pool/create/tiers/portfolio/charts, a11y, responsive, cross-browser, the Playwright e2e projects) I'm batching into the next pass.

What passed, with real evidence:

  • INF: fresh bootstrap + qa-verify-deploy + idempotent stop/start-qa + PG-1 (cl8y_legal).
  • Indexer (IDX-00-01..08): health/swagger, route/solve GET + POST validation (400 not 500 on bad hybrid_by_hop), injection + negative-limit caps clamp, CG/CMC shapes, hybrid-volume L10 reconciles, oracle + hooks endpoints, and live sync-after-swap (one EMBER->CORAL, row + candle landed under a second). #285 lifecycle scoping confirmed live: a forged contract_address doesn't attribute a fill to a victim pair (parser + integration + a live limit_order_fill scoped by _contract_address).
  • Contracts (ONC): smoke pool sim, factory pause actually blocks both swap and limit-place ("Contract is paused") and unpauses clean, fee-discount is_trusted_router = true for the router.
  • Slippage / #293 (SW-00-04, SEC-00-05, LR-00-12): verify-issue-293 green - route/solve carries spot_amount_out + slippage_percent, math-consistent, and pool_only EMBER->CORAL quotes 99.99% so the retail >30% Expert-Mode block has something to fire on.
  • Security: rate-limit returns 429 under burst (180/200 at RATE_LIMIT_RPS=60), CORS rejects unknown origins and echoes the allowlist, blacklist-check returns clean JSON.
  • Reorg safety (#287): rewound the indexer cursor and replayed ~3900 blocks - swap_events stayed put, zero dup (tx_hash, pair_id, swap_index). ON CONFLICT holds.
  • Regression gates: contracts 438/0, indexer lib 134/0, indexer integration 467/0, charts integration 7/0, fee-tier doc drift + lint green. Frontend unit is 891/893; the only 2 fails are the known terraExplorer 127.0.0.1-vs-localhost env artifact, not a regression.

Two real things I found and fixed:

  1. npm run build is red on main at 038a457 - tsc -b fails with 2 type errors: priceChartLightweightSeriesSync.ts (the #336 chart-viewport file) has an unconstrained SeriesApi, and useTerraBroadcastMutation.ts (the #305 onMutate wrapper) returns void instead of the mutation context. vite build alone is fine so it slipped - CI runs vitest + eslint but not tsc -b. Fix is type-only; tsc -b + npm run build green after, dist still ships no sourcemaps (#117 holds), chart + broadcast units pass. MR !834 (commit 6cc9e92). Worth adding tsc -b to CI so this stops recurring (same shape as the #246 break).
  2. verify-issue-285 was failing its live layer - but it's the harness, not the fix: it builds a pure-book hybrid swap with no slippage floor, which the #334 guard now correctly rejects, so the book leg never filled. Added a min_return floor; re-run is 12/0 with the live limit_order_fill attribution confirmed. That's the same thing that made the Cloud Agent's REG-00-08 #285 run fail. MR !835 (commit f695c6d).

Smaller stuff:

  • Checklist doc-nits: CFG-00-01 lists VITE_LCD_URL / VITE_RPC_URL but the real vars are VITE_TERRA_LCD_URL / VITE_TERRA_RPC_URL; ONC-00-03's is_trusted_router field is addr, not address; route_solver's doc-comment still says global_v1 but it answers global_v3.
  • make test-charts-integration seeds a synthetic swap row into the live dex_indexer DB (the one the running indexer serves), not an isolated test DB - minor, but it pollutes the live store.
  • RATE_LIMIT_RPS=0 is the current QA default (rate-limiting off); the limiter itself works (verified at 60). Prod needs it set.

Counts so far: 36 PASS, 2 partial (REG-00-02 the env artifact; SEC-00-05 indexer-side confirmed, the UI submit-block batched into the browser pass), 3 deferred-with-reason (ONC-00-04 hybrid is out of pool-only launch scope per the readiness matrix; EDGE-00-04/05 covered by contract + #287 integration tests). The rest is the browser pass plus the LR-00 gates, batched next.

@PlasticDigits - two small MRs up: !834 (the red npm run build on main) and !835 (verify-285 harness). The build one is worth pulling in before the next checklist pass.

Worked the whole no-browser half of this checklist on a fresh `make reset-qa` at `038a457` (clean genesis: 25 pairs / 60 swaps / 14 assets, USTC-C unique so the #293 enrichment path is live). Posting this as progress, not a sign-off — it's the contract + indexer + source layer. The browser/UI matrix (wallets, nav, swap/trade/limits/pool/create/tiers/portfolio/charts, a11y, responsive, cross-browser, the Playwright e2e projects) I'm batching into the next pass. What passed, with real evidence: - INF: fresh bootstrap + qa-verify-deploy + idempotent stop/start-qa + PG-1 (cl8y_legal). - Indexer (IDX-00-01..08): health/swagger, route/solve GET + POST validation (400 not 500 on bad hybrid_by_hop), injection + negative-limit caps clamp, CG/CMC shapes, hybrid-volume L10 reconciles, oracle + hooks endpoints, and live sync-after-swap (one EMBER->CORAL, row + candle landed under a second). #285 lifecycle scoping confirmed live: a forged contract_address doesn't attribute a fill to a victim pair (parser + integration + a live limit_order_fill scoped by _contract_address). - Contracts (ONC): smoke pool sim, factory pause actually blocks both swap and limit-place ("Contract is paused") and unpauses clean, fee-discount is_trusted_router = true for the router. - Slippage / #293 (SW-00-04, SEC-00-05, LR-00-12): verify-issue-293 green - route/solve carries spot_amount_out + slippage_percent, math-consistent, and pool_only EMBER->CORAL quotes 99.99% so the retail >30% Expert-Mode block has something to fire on. - Security: rate-limit returns 429 under burst (180/200 at RATE_LIMIT_RPS=60), CORS rejects unknown origins and echoes the allowlist, blacklist-check returns clean JSON. - Reorg safety (#287): rewound the indexer cursor and replayed ~3900 blocks - swap_events stayed put, zero dup (tx_hash, pair_id, swap_index). ON CONFLICT holds. - Regression gates: contracts 438/0, indexer lib 134/0, indexer integration 467/0, charts integration 7/0, fee-tier doc drift + lint green. Frontend unit is 891/893; the only 2 fails are the known terraExplorer 127.0.0.1-vs-localhost env artifact, not a regression. Two real things I found and fixed: 1. `npm run build` is red on main at 038a457 - tsc -b fails with 2 type errors: priceChartLightweightSeriesSync.ts (the #336 chart-viewport file) has an unconstrained SeriesApi<T>, and useTerraBroadcastMutation.ts (the #305 onMutate wrapper) returns void instead of the mutation context. vite build alone is fine so it slipped - CI runs vitest + eslint but not tsc -b. Fix is type-only; tsc -b + npm run build green after, dist still ships no sourcemaps (#117 holds), chart + broadcast units pass. MR !834 (commit 6cc9e92). Worth adding tsc -b to CI so this stops recurring (same shape as the #246 break). 2. verify-issue-285 was failing its live layer - but it's the harness, not the fix: it builds a pure-book hybrid swap with no slippage floor, which the #334 guard now correctly rejects, so the book leg never filled. Added a min_return floor; re-run is 12/0 with the live limit_order_fill attribution confirmed. That's the same thing that made the Cloud Agent's REG-00-08 #285 run fail. MR !835 (commit f695c6d). Smaller stuff: - Checklist doc-nits: CFG-00-01 lists VITE_LCD_URL / VITE_RPC_URL but the real vars are VITE_TERRA_LCD_URL / VITE_TERRA_RPC_URL; ONC-00-03's is_trusted_router field is `addr`, not `address`; route_solver's doc-comment still says global_v1 but it answers global_v3. - make test-charts-integration seeds a synthetic swap row into the live dex_indexer DB (the one the running indexer serves), not an isolated test DB - minor, but it pollutes the live store. - RATE_LIMIT_RPS=0 is the current QA default (rate-limiting off); the limiter itself works (verified at 60). Prod needs it set. Counts so far: 36 PASS, 2 partial (REG-00-02 the env artifact; SEC-00-05 indexer-side confirmed, the UI submit-block batched into the browser pass), 3 deferred-with-reason (ONC-00-04 hybrid is out of pool-only launch scope per the readiness matrix; EDGE-00-04/05 covered by contract + #287 integration tests). The rest is the browser pass plus the LR-00 gates, batched next. @PlasticDigits - two small MRs up: !834 (the red npm run build on main) and !835 (verify-285 harness). The build one is worth pulling in before the next checklist pass.
Brouie commented 2026-06-08 03:52:18 +00:00 (Migrated from gitlab.com)

Browser-pass update (continuing from the no-browser note above). Worked through the live dApp UI against the QA stack — still a progress checkpoint, not the LR-00 sign-off.

Verified live in the UI (on-chain actions cross-checked against the tx + indexer from the back end):

  • Shell / wallet / config: all primary routes render, deep-link to /trade/, invalid-route handling, theme persistence, /my-portfolio redirect (NAV-00-01..05). Simulated Wallet connects as the funded dev account (WL-00-03). Runs on Node 24 (INF-00-05). CORS works on both localhost and 127.0.0.1 (CFG-00-02). Expert-Mode + slippage settings persist across reload (CFG-00-04). Frontend<->indexer contract clean, no console errors (INT-00-01).
  • Swap: direct pool swap executes end to end — confirmed the on-chain tx + the indexer swap row + candle from both ends (SW-00-01, IDX-00-05). Hybrid pool+book disclosure matched the on-chain legs exactly (SW-00-08). Retail >30% slippage is hard-blocked and only proceeds with Expert-Mode acknowledgement (SW-00-04, SEC-00-05). Indexer-outage banner is honest (SW-00-06). Pause blocks the swap with clear copy (SW-00-09). Multi-hop route display renders ordered hops (SW-00-02).
  • Trade / Limits: workspace loads chart+book+tape, pair selector with no layout jump (TR-00-01, TR-00-05); limit place -> escrow -> cancel -> full refund verified on-chain (LT-00-01); indexer-outage degrades honestly on /trade and /limits (TR-00-06, LT-00-08).
  • Pool / Charts / Portfolio / Protocol: pool list search/sort/paginate + router-known badges (PL-00-01, PL-00-05); chart candles across intervals, chart matches last trade, indicators render, outage banner (CH-00-01..04); portfolio positions / open limits / LP / history / trader-profile link (PF-00-01..03); oracle price shows in the UI (PR-00-01).
  • Edge / error / security / obs: zero-amount + dust display handled (EDGE-00-01/02); insufficient-balance preflight blocks before the wallet popup (ERR-00-04); legal/NFA footer on every page (SEC-00-04); tx explorer + confirming links work (OBS-00-02/03); create-pair validation gates (CP-00-01).

Findings from this pass:

  1. Test isolation: make test-charts-integration seeds fixtures (a placeholder pair terra1paircontractabc, token terra1ustctoken, trader terra1traderxyz, swap charts_int_tx_1) into the LIVE indexer DB rather than an isolated one. They surface in the UI — a broken "LUNC / USTC - decoding bech32 failed" pair in /pool, a phantom trader on the leaderboard, and the "indexer 26 vs factory 25" pair-count mismatch. I purged the live copy; the real fix is pointing that test at its own DB. (Extends the earlier REG-00-05 note.)

  2. Slippage guard on the lopsided seed topology (#293): the best-execution router prefers junk multi-hop routes and the retail >30% guard blocks essentially every swap — even a fair direct EMBER/CORAL swap (0% hop spread) reports ~99.99% "vs best-route token prices" because the reference prices are skewed by the seed pools. The guard is behaving correctly and conservatively; it's the seed data that's lopsided. Net effect on this stack: executing any swap needs Expert Mode. On balanced liquidity this won't over-block. (SW-00-01 was therefore verified via an Expert-Mode execution.)

  3. Pause UX (#87): pausing a single pool is route-specific — if the router can detour around the paused pool it won't show a pause banner (correct, since only that pool is paused), and the pause message surfaces at submit rather than pre-quote. Minor, worth a look.

Batched for the next pass: the wallet matrix (Keplr / Station / WalletConnect / reject-recovery / Leap), liquidity add/remove + create-pair + tier register (on-chain), market-order + book-edit + ladder/batch/claim limit flows, a11y, responsive, cross-browser, perf, and the Playwright e2e projects + verify-295 — then the LR-00 sign-off.

Browser-pass update (continuing from the no-browser note above). Worked through the live dApp UI against the QA stack — still a progress checkpoint, not the LR-00 sign-off. Verified live in the UI (on-chain actions cross-checked against the tx + indexer from the back end): - Shell / wallet / config: all primary routes render, deep-link to /trade/<pair>, invalid-route handling, theme persistence, /my-portfolio redirect (NAV-00-01..05). Simulated Wallet connects as the funded dev account (WL-00-03). Runs on Node 24 (INF-00-05). CORS works on both localhost and 127.0.0.1 (CFG-00-02). Expert-Mode + slippage settings persist across reload (CFG-00-04). Frontend<->indexer contract clean, no console errors (INT-00-01). - Swap: direct pool swap executes end to end — confirmed the on-chain tx + the indexer swap row + candle from both ends (SW-00-01, IDX-00-05). Hybrid pool+book disclosure matched the on-chain legs exactly (SW-00-08). Retail >30% slippage is hard-blocked and only proceeds with Expert-Mode acknowledgement (SW-00-04, SEC-00-05). Indexer-outage banner is honest (SW-00-06). Pause blocks the swap with clear copy (SW-00-09). Multi-hop route display renders ordered hops (SW-00-02). - Trade / Limits: workspace loads chart+book+tape, pair selector with no layout jump (TR-00-01, TR-00-05); limit place -> escrow -> cancel -> full refund verified on-chain (LT-00-01); indexer-outage degrades honestly on /trade and /limits (TR-00-06, LT-00-08). - Pool / Charts / Portfolio / Protocol: pool list search/sort/paginate + router-known badges (PL-00-01, PL-00-05); chart candles across intervals, chart matches last trade, indicators render, outage banner (CH-00-01..04); portfolio positions / open limits / LP / history / trader-profile link (PF-00-01..03); oracle price shows in the UI (PR-00-01). - Edge / error / security / obs: zero-amount + dust display handled (EDGE-00-01/02); insufficient-balance preflight blocks before the wallet popup (ERR-00-04); legal/NFA footer on every page (SEC-00-04); tx explorer + confirming links work (OBS-00-02/03); create-pair validation gates (CP-00-01). Findings from this pass: 1. Test isolation: `make test-charts-integration` seeds fixtures (a placeholder pair `terra1paircontractabc`, token `terra1ustctoken`, trader `terra1traderxyz`, swap `charts_int_tx_1`) into the LIVE indexer DB rather than an isolated one. They surface in the UI — a broken "LUNC / USTC - decoding bech32 failed" pair in /pool, a phantom trader on the leaderboard, and the "indexer 26 vs factory 25" pair-count mismatch. I purged the live copy; the real fix is pointing that test at its own DB. (Extends the earlier REG-00-05 note.) 2. Slippage guard on the lopsided seed topology (#293): the best-execution router prefers junk multi-hop routes and the retail >30% guard blocks essentially every swap — even a fair direct EMBER/CORAL swap (0% hop spread) reports ~99.99% "vs best-route token prices" because the reference prices are skewed by the seed pools. The guard is behaving correctly and conservatively; it's the seed data that's lopsided. Net effect on this stack: executing any swap needs Expert Mode. On balanced liquidity this won't over-block. (SW-00-01 was therefore verified via an Expert-Mode execution.) 3. Pause UX (#87): pausing a single pool is route-specific — if the router can detour around the paused pool it won't show a pause banner (correct, since only that pool is paused), and the pause message surfaces at submit rather than pre-quote. Minor, worth a look. Batched for the next pass: the wallet matrix (Keplr / Station / WalletConnect / reject-recovery / Leap), liquidity add/remove + create-pair + tier register (on-chain), market-order + book-edit + ladder/batch/claim limit flows, a11y, responsive, cross-browser, perf, and the Playwright e2e projects + verify-295 — then the LR-00 sign-off.
PlasticDigits commented 2026-06-08 05:14:06 +00:00 (Migrated from gitlab.com)

mentioned in commit 9d3bf713e5

mentioned in commit 9d3bf713e513a36bb8f0ce7a76a33d1c390d5bf0
ghost1 commented 2026-06-08 05:24:17 +00:00 (Migrated from gitlab.com)

mentioned in commit f875d5388a

mentioned in commit f875d5388a17e2467de35f7dc805ee7d77e6cea7
ghost1 commented 2026-06-08 05:24:40 +00:00 (Migrated from gitlab.com)

mentioned in commit 06eb2d8bb5

mentioned in commit 06eb2d8bb5bd7a30fa9d33e87c5d319082f06e1f
PlasticDigits commented 2026-06-08 08:43:13 +00:00 (Migrated from gitlab.com)

mentioned in commit 0675d67711

mentioned in commit 0675d67711d5cff2c46ee3fd9b68bf88ce15f74c
PlasticDigits commented 2026-06-08 08:43:13 +00:00 (Migrated from gitlab.com)

mentioned in commit 0e3afcaef3

mentioned in commit 0e3afcaef332b416792e99676407524ae3be2ef3
PlasticDigits commented 2026-06-08 08:43:13 +00:00 (Migrated from gitlab.com)

mentioned in commit 449c51ba01

mentioned in commit 449c51ba011cfb182a9e63df63440a3996d4a470
PlasticDigits commented 2026-06-08 08:43:13 +00:00 (Migrated from gitlab.com)

mentioned in commit a92891c4fc

mentioned in commit a92891c4fc52bbd48a7747f4bd0465d52213f698
PlasticDigits commented 2026-06-08 08:43:14 +00:00 (Migrated from gitlab.com)

mentioned in commit 53b8658c58

mentioned in commit 53b8658c5850c50e45fdd163758ea9978315fc56
PlasticDigits commented 2026-06-08 13:42:28 +00:00 (Migrated from gitlab.com)

mentioned in commit 456886c2ea

mentioned in commit 456886c2ea3d298740c2af65a4f6c710dd18380a
PlasticDigits commented 2026-06-08 13:42:28 +00:00 (Migrated from gitlab.com)

mentioned in commit 8f0ca4009d

mentioned in commit 8f0ca4009d3de0758929779faf1aaa3703d3394a
PlasticDigits commented 2026-06-08 13:42:30 +00:00 (Migrated from gitlab.com)

mentioned in commit 081abcdffa

mentioned in commit 081abcdffa4f6f67baff6edb5e6401f398a7200d
PlasticDigits commented 2026-06-08 13:42:30 +00:00 (Migrated from gitlab.com)

mentioned in commit 65876e17c7

mentioned in commit 65876e17c74fed89111b3928c9e2229ded5eb4de
PlasticDigits commented 2026-06-08 13:42:30 +00:00 (Migrated from gitlab.com)

mentioned in commit c5687c6e3f

mentioned in commit c5687c6e3f9f8014df08123a92700bd77315d4a1
Brouie commented 2026-06-09 02:16:02 +00:00 (Migrated from gitlab.com)

mentioned in merge request !843

mentioned in merge request !843
Brouie commented 2026-06-09 02:17:29 +00:00 (Migrated from gitlab.com)

Picking the local pass back up — quick state and what's verified since.

Environment: brought the stack back up from its volumes after a restart — same deployed build, no redeploy, chain + indexer + DB intact. Earlier two fixes both merged (build-break tsc fix, verify-285 slippage floor).

Limit-order lifecycle, all cross-checked on-chain:

  • Batch + ladder placement (#295): one place_limit_order_batch per action, rungs land at the right prices, escrow debits net of the 90bps maker fee. The ladder UI correctly refuses asks that would cross the best bid and says why.
  • Price-only edit (#247): single update_limit_order_price — same order id, price changes in place, escrow untouched, no cancel/replace.
  • Claim single expired: one claim_expired_limit_order + one transfer each, full refund.
  • Claim-all parked: one claim_expired_limit_orders batch (batch_count=2), single combined refund — the #259 gas-saver. Both orders flip to refunded in the same tx.
  • Liquidity (contract): provide_liquidity clean (transfer_from x2 + mint), withdraw clean (burn + transfer x2).

Two findings:

  • Add-liquidity is gas-underestimated in the dapp. ADD_LIQUIDITY_GAS_LIMIT=500000 but provide_liquidity actually costs ~507.5k on-chain, so it OOGs every attempt and the retry can't help (fixed limit, not simulated). Fix in MR !843 (bump to 650k; withdraw 600k / create 800k already have headroom). Same family as #343, different path.
  • The two park harnesses (#339 seed + verify-309) were reverting on the #334 guard — fixed + verified, MR !842.

On your PP2 wave: #341 (multi-hop price-impact hard-block even with Expert Mode) matches what I hit in the swap pass. #342 (native-LUNC "Cannot Sub") — the deployed contract's max_spread subtraction is guarded, so the one reachable unguarded Decimal sub I can see is provide_liquidity's Decimal::one() - tolerance (panics if tolerance > 1); no repro steps on the issue so I'm not calling root cause.

Still batched: wallet matrix, market order + rest of the trade page, create-pair, fee tiers, a11y/responsive/cross-browser, outage + boundary error checks, the e2e projects, then LR-00 sign-off. Sign-off stays gated on the open PP2 items clearing. !842/!843 need your merge — @PlasticDigits.

Picking the local pass back up — quick state and what's verified since. Environment: brought the stack back up from its volumes after a restart — same deployed build, no redeploy, chain + indexer + DB intact. Earlier two fixes both merged (build-break tsc fix, verify-285 slippage floor). Limit-order lifecycle, all cross-checked on-chain: - Batch + ladder placement (#295): one place_limit_order_batch per action, rungs land at the right prices, escrow debits net of the 90bps maker fee. The ladder UI correctly refuses asks that would cross the best bid and says why. - Price-only edit (#247): single update_limit_order_price — same order id, price changes in place, escrow untouched, no cancel/replace. - Claim single expired: one claim_expired_limit_order + one transfer each, full refund. - Claim-all parked: one claim_expired_limit_orders batch (batch_count=2), single combined refund — the #259 gas-saver. Both orders flip to refunded in the same tx. - Liquidity (contract): provide_liquidity clean (transfer_from x2 + mint), withdraw clean (burn + transfer x2). Two findings: - Add-liquidity is gas-underestimated in the dapp. ADD_LIQUIDITY_GAS_LIMIT=500000 but provide_liquidity actually costs ~507.5k on-chain, so it OOGs every attempt and the retry can't help (fixed limit, not simulated). Fix in MR !843 (bump to 650k; withdraw 600k / create 800k already have headroom). Same family as #343, different path. - The two park harnesses (#339 seed + verify-309) were reverting on the #334 guard — fixed + verified, MR !842. On your PP2 wave: #341 (multi-hop price-impact hard-block even with Expert Mode) matches what I hit in the swap pass. #342 (native-LUNC "Cannot Sub") — the deployed contract's max_spread subtraction is guarded, so the one reachable unguarded Decimal sub I can see is provide_liquidity's `Decimal::one() - tolerance` (panics if tolerance > 1); no repro steps on the issue so I'm not calling root cause. Still batched: wallet matrix, market order + rest of the trade page, create-pair, fee tiers, a11y/responsive/cross-browser, outage + boundary error checks, the e2e projects, then LR-00 sign-off. Sign-off stays gated on the open PP2 items clearing. !842/!843 need your merge — @PlasticDigits.
Brouie commented 2026-06-09 02:58:22 +00:00 (Migrated from gitlab.com)

mentioned in issue #345

mentioned in issue #345
Brouie commented 2026-06-09 02:58:56 +00:00 (Migrated from gitlab.com)

CP-00-02 create pair — filed as #345. Dapp create-pair is broken two ways: createPair never attaches the #276 fee (factory.ts, no coins arg), and CREATE_PAIR_GAS_LIMIT=800000 is under the real 871552 gas. Contract is fine — terrad create_pair with the fee attached instantiated the pair clean. Handed to the pipeline.

Also since the last note:

  • TR-00-02 market order: small EMBER->CORAL sell took bid #1 @1.0 (better than pool 0.987), so the hybrid router routed to the book optimally — 5 EMBER -> 4.955 CORAL, bid #1 remaining dropped exactly 5, indexer recorded the swap.
  • PL-00-03 withdraw liquidity: dapp burn 100 LP -> 100.67 EMBER + 99.34 CORAL back, balances reconcile to the unit, fits the 600k gas limit (withdraw works; only add/create are gas-under).
CP-00-02 create pair — filed as #345. Dapp create-pair is broken two ways: createPair never attaches the #276 fee (factory.ts, no coins arg), and CREATE_PAIR_GAS_LIMIT=800000 is under the real 871552 gas. Contract is fine — terrad create_pair with the fee attached instantiated the pair clean. Handed to the pipeline. Also since the last note: - TR-00-02 market order: small EMBER->CORAL sell took bid #1 @1.0 (better than pool 0.987), so the hybrid router routed to the book optimally — 5 EMBER -> 4.955 CORAL, bid #1 remaining dropped exactly 5, indexer recorded the swap. - PL-00-03 withdraw liquidity: dapp burn 100 LP -> 100.67 EMBER + 99.34 CORAL back, balances reconcile to the unit, fits the 600k gas limit (withdraw works; only add/create are gas-under).
Brouie commented 2026-06-10 01:51:41 +00:00 (Migrated from gitlab.com)

mentioned in issue #353

mentioned in issue #353
Brouie commented 2026-06-10 02:21:24 +00:00 (Migrated from gitlab.com)

mentioned in issue #355

mentioned in issue #355
Brouie commented 2026-06-10 02:30:39 +00:00 (Migrated from gitlab.com)

Browser-pass checkpoint (still progress, not the LR-00 sign-off). Continuing on the laptop dapp against the QA stack at main 83dc192, on-chain actions cross-checked from the back end. This batch was the re-test of the merged fix wave plus the rows it was blocking.

PASS:

  • PL-00-02 add liquidity: tx 71A80C84..., gasUsed 507,633 against the raised 650k limit (!843) — the exact value that OOG'd at the old 500k. Two-step allowance + transfer_from x2 + provide_liquidity + mint.
  • PL-00-04 wrap in provide: tx 7644744E..., wrap_deposit + notify_deposit + allowance + provide + mint in one tx, post-tax amounts correct, within budget.
  • CP-00-02 create pair: tx AA13D05A..., the #276 fee (100 LUNC) now attaches in funds (the #345 fix, live) and gasUsed 871,252 fits the raised limit; factory pair count 26 -> 27. New pair is factory-only until it trades (indexer lazy-discovery, #311) — expected, not a fail.
  • SW-00-05 Max button: reserve math exact — the dapp reserves 1,970,000 gas worth of fees and fills Max = balance - reserve to the micro-unit.
  • SW-00-07 / FT-00-01 fee tiers: tier 9 active, tier ladder and effective-fee table correct; quoted fee 0.09%.
  • #341 multi-hop preflight (the merged fix): VERIFIED working — multi-hop swaps now pass the per-hop spread guard and reach broadcast under Expert Mode, instead of the old blanket "price impact too high" block.

FAIL / new issues filed:

  • SW-00-03 native wrap swap -> #353: deterministic out-of-gas. Broadcast budget 1,140,000 vs real ~1.59M because the wrap path routes its single hop through the router (priced as direct-to-pair) and WRAP_GAS_LIMIT is under the real wrap_deposit cost. Same note also captures 2-hop CW20 execution OOG and that the Max-reserve estimator already prices this tx at 1.97M while broadcast grants 1.14M.
  • TR pair click-switch -> #354 (blocker-class): clicking a different pair crashes the whole trade view to the ErrorBoundary. The workspace prefetch seeds a flat limit-book page into the query key the order book consumes as an infinite query, so the panel throws during render. Deep links and URL navigation are fine; only click-switch trips it.
  • Indexer rate limiter -> #355 (High, prod-facing): tower_governor per_second(rps) sets the replenish period, not the rate, so every limit runs at 1/rps of intended (lcd-heavy "10 RPS" is really burst 20 then 1 req/10s per IP, shared across all book/route-solve routes). Surfaced as live 429s on the book endpoints during this pass. Also a QA note: RATE_LIMIT_RPS=0 only disables the general layer; lcd-heavy has its own var.

Net effect on the checklist: PL-00-02, PL-00-04, CP-00-02, SW-00-05, SW-00-07, FT-00-01 move to PASS. SW-00-03 stays FAIL pending #353. The trade-page rows (TR/LT) are gated on #354 for click-switch; I can still work them via URL navigation and will. LR-00 sign-off remains blocked on the open P0/P1s: #350, #353, #354, #355 (and the earlier #341/#342/#345 are now resolved/closed).

Still to run this pass: TR-00-03/04/07, LT-00-04/07, the wallet matrix, a11y/responsive/cross-browser/perf/concurrency, e2e projects + verify-295, remaining edge/error/integration rows, then LR-00.

Browser-pass checkpoint (still progress, not the LR-00 sign-off). Continuing on the laptop dapp against the QA stack at main 83dc192, on-chain actions cross-checked from the back end. This batch was the re-test of the merged fix wave plus the rows it was blocking. PASS: - PL-00-02 add liquidity: tx 71A80C84..., gasUsed 507,633 against the raised 650k limit (!843) — the exact value that OOG'd at the old 500k. Two-step allowance + transfer_from x2 + provide_liquidity + mint. - PL-00-04 wrap in provide: tx 7644744E..., wrap_deposit + notify_deposit + allowance + provide + mint in one tx, post-tax amounts correct, within budget. - CP-00-02 create pair: tx AA13D05A..., the #276 fee (100 LUNC) now attaches in funds (the #345 fix, live) and gasUsed 871,252 fits the raised limit; factory pair count 26 -> 27. New pair is factory-only until it trades (indexer lazy-discovery, #311) — expected, not a fail. - SW-00-05 Max button: reserve math exact — the dapp reserves 1,970,000 gas worth of fees and fills Max = balance - reserve to the micro-unit. - SW-00-07 / FT-00-01 fee tiers: tier 9 active, tier ladder and effective-fee table correct; quoted fee 0.09%. - #341 multi-hop preflight (the merged fix): VERIFIED working — multi-hop swaps now pass the per-hop spread guard and reach broadcast under Expert Mode, instead of the old blanket "price impact too high" block. FAIL / new issues filed: - SW-00-03 native wrap swap -> #353: deterministic out-of-gas. Broadcast budget 1,140,000 vs real ~1.59M because the wrap path routes its single hop through the router (priced as direct-to-pair) and WRAP_GAS_LIMIT is under the real wrap_deposit cost. Same note also captures 2-hop CW20 execution OOG and that the Max-reserve estimator already prices this tx at 1.97M while broadcast grants 1.14M. - TR pair click-switch -> #354 (blocker-class): clicking a different pair crashes the whole trade view to the ErrorBoundary. The workspace prefetch seeds a flat limit-book page into the query key the order book consumes as an infinite query, so the panel throws during render. Deep links and URL navigation are fine; only click-switch trips it. - Indexer rate limiter -> #355 (High, prod-facing): tower_governor per_second(rps) sets the replenish period, not the rate, so every limit runs at 1/rps of intended (lcd-heavy "10 RPS" is really burst 20 then 1 req/10s per IP, shared across all book/route-solve routes). Surfaced as live 429s on the book endpoints during this pass. Also a QA note: RATE_LIMIT_RPS=0 only disables the general layer; lcd-heavy has its own var. Net effect on the checklist: PL-00-02, PL-00-04, CP-00-02, SW-00-05, SW-00-07, FT-00-01 move to PASS. SW-00-03 stays FAIL pending #353. The trade-page rows (TR/LT) are gated on #354 for click-switch; I can still work them via URL navigation and will. LR-00 sign-off remains blocked on the open P0/P1s: #350, #353, #354, #355 (and the earlier #341/#342/#345 are now resolved/closed). Still to run this pass: TR-00-03/04/07, LT-00-04/07, the wallet matrix, a11y/responsive/cross-browser/perf/concurrency, e2e projects + verify-295, remaining edge/error/integration rows, then LR-00.
Brouie commented 2026-06-10 02:41:41 +00:00 (Migrated from gitlab.com)

Reconciled progress tally against the full checklist, so the scope is explicit. 135 rows total (120 scenarios + 15 LR-00 sign-off).

  • PASS: 82
  • DEFER / waived / partial-benign: 6
  • FAIL (open): 1 — SW-00-03 (#353)
  • LEFT to verify: 46 (31 functional rows + the 15 LR-00 sign-off rows, which run last)

DEFER / waived (6):

  • ONC-00-04, SW-00-08 — hybrid out-of-pool-only scope per the readiness matrix (DEX-P1-003/005)
  • EDGE-00-04, EDGE-00-05 — covered by contract + #287 integration tests (timing / multiswap)
  • REG-00-02 — partial-benign 891/893 (the known terraExplorer 127.0.0.1-vs-localhost env artifact; green on CI/default env)
  • REG-00-05 — charts integration passes 7/0 but seeds a fixture into the live DB; isolation fix still owed

The 31 functional rows left, grouped:

  • Wallet matrix (7): WL-00-01/02/04/05/06/07 — Keplr, Station, not-installed UX, WalletConnect, reject-recovery, Leap (needs the browser extensions)
  • Trade / Limits (4): TR-00-03, TR-00-07, LT-00-04, LT-00-07 — in progress now
  • Error handling (3): ERR-00-01/02/03 — LCD outage during quote, ErrorBoundary recovery, tx timeout
  • Responsive / cross-browser (5): RES-00-01/02, XBR-00-01/02/03
  • Perf / concurrency (4): PERF-00-01/02, CON-00-02/03
  • E2E regression (3): REG-00-06/07/08 — Playwright projects + verify-295
  • Integration / config / edge (5): INT-00-02/06, CFG-00-03, EDGE-00-03/06, INF-00-04

Note on the 82: that's the cumulative PASS across the no-browser sweep + the browser passes. Some were verified at the contract/source layer or on an earlier build; the LR-00 sign-off wants each LR row re-confirmed at the UI on the final SHA, and the merged-fix rows (PL-00-02, PL-00-04, CP-00-02, SW-00-05/07) only went green today. So the real remaining work is those 31 + 15 LR re-confirmations.

LR-00 sign-off stays blocked on the open P0/P1 set: #350, #353, #354, #355. Continuing the trade/limits rows next (via URL navigation, since #354 makes click-switch crash).

Reconciled progress tally against the full checklist, so the scope is explicit. 135 rows total (120 scenarios + 15 LR-00 sign-off). - PASS: 82 - DEFER / waived / partial-benign: 6 - FAIL (open): 1 — SW-00-03 (#353) - LEFT to verify: 46 (31 functional rows + the 15 LR-00 sign-off rows, which run last) DEFER / waived (6): - ONC-00-04, SW-00-08 — hybrid out-of-pool-only scope per the readiness matrix (DEX-P1-003/005) - EDGE-00-04, EDGE-00-05 — covered by contract + #287 integration tests (timing / multiswap) - REG-00-02 — partial-benign 891/893 (the known terraExplorer 127.0.0.1-vs-localhost env artifact; green on CI/default env) - REG-00-05 — charts integration passes 7/0 but seeds a fixture into the live DB; isolation fix still owed The 31 functional rows left, grouped: - Wallet matrix (7): WL-00-01/02/04/05/06/07 — Keplr, Station, not-installed UX, WalletConnect, reject-recovery, Leap (needs the browser extensions) - Trade / Limits (4): TR-00-03, TR-00-07, LT-00-04, LT-00-07 — in progress now - Error handling (3): ERR-00-01/02/03 — LCD outage during quote, ErrorBoundary recovery, tx timeout - Responsive / cross-browser (5): RES-00-01/02, XBR-00-01/02/03 - Perf / concurrency (4): PERF-00-01/02, CON-00-02/03 - E2E regression (3): REG-00-06/07/08 — Playwright projects + verify-295 - Integration / config / edge (5): INT-00-02/06, CFG-00-03, EDGE-00-03/06, INF-00-04 Note on the 82: that's the cumulative PASS across the no-browser sweep + the browser passes. Some were verified at the contract/source layer or on an earlier build; the LR-00 sign-off wants each LR row re-confirmed at the UI on the final SHA, and the merged-fix rows (PL-00-02, PL-00-04, CP-00-02, SW-00-05/07) only went green today. So the real remaining work is those 31 + 15 LR re-confirmations. LR-00 sign-off stays blocked on the open P0/P1 set: #350, #353, #354, #355. Continuing the trade/limits rows next (via URL navigation, since #354 makes click-switch crash).
Brouie commented 2026-06-10 05:32:36 +00:00 (Migrated from gitlab.com)

Batch B — trade/limit-order rows, all on EMBER/CORAL, on-chain cross-checked. Pair switching avoided per #354 (these don't need it).

  • TR-00-03 limit place + view: PASS. Placed via the dapp ticket, landed and rests in the book, shows in placements. tx E20CFED2 (order 14, ask @1.05, 5 EMBER, 4bps maker fee -> 4,998,000 escrow, code 0). Sell side was intentional.
  • TR-00-04 price-only edit: PASS. Single update_limit_order_price on order 1 (-> 0.96), escrow untouched (33.54M remaining), no cancel/replace, gasUsed 226,081. tx 10D756F5. Confirms #247 in the dapp.
  • LT-00-04 gas presets (#204): PASS. The Low/Medium/High selector is wired into the broadcast — decoded the placement hooks and the per-order max_adjust_steps changes with the preset (Low = 32, higher = 128), i.e. the #260 adaptive floor 32 / cap 256 book-walk budget. tx 132D25A2 (order 15). One copy nit worth a look (not a blocker): the preset controls the contract-side walk budget, but the broadcast gas limit (gasLimitForLimitOrderBatch) scales with rung count only, so the tx is always funded for the worst case. Result: the displayed "Est. network fee: ~22.09 LUNC" is identical across all three presets and both single-order placements broadcast at gasWanted 580,000. The helper text "Uses less gas / Uses more gas" reads as a cost difference that the UI never shows — it's really a reliability control (succeed on deep books), so the copy is slightly misleading. P3.
  • LT-00-07 deep order book pagination: PASS. Seeded the ask side to 39 resting rungs (prices to ~1.80); the dapp order book pages on scroll (infinite query, has_more honored), prices ascend cleanly, no crash/flicker/dupes. API page1 limit 20 -> 20 orders has_more=true.
  • TR-00-07 responsive trade layout: PASS (iPad/desktop-narrow, panels stack and stay reachable, no overlap).

Checklist moves to PASS: TR-00-03, TR-00-04, TR-00-07, LT-00-04, LT-00-07. New tally: 87 PASS / 6 defer / 1 fail (#353) / 41 left (26 functional + 15 LR-00). Remaining functional: WL matrix (7), ERR-00-01/02/03, RES-00-01/02, XBR-00-01/02/03, PERF-00-01/02, CON-00-02/03, REG-00-06/07/08, INT-00-02/06, CFG-00-03, EDGE-00-03/06, INF-00-04. LR-00 still gated on #350/#353/#354/#355.

(Note: the live QA stack picked up several new resting asks from my deep-book seed on pair 1 — session test state, clears on the next reset.)

Batch B — trade/limit-order rows, all on EMBER/CORAL, on-chain cross-checked. Pair switching avoided per #354 (these don't need it). - TR-00-03 limit place + view: PASS. Placed via the dapp ticket, landed and rests in the book, shows in placements. tx E20CFED2 (order 14, ask @1.05, 5 EMBER, 4bps maker fee -> 4,998,000 escrow, code 0). Sell side was intentional. - TR-00-04 price-only edit: PASS. Single update_limit_order_price on order 1 (-> 0.96), escrow untouched (33.54M remaining), no cancel/replace, gasUsed 226,081. tx 10D756F5. Confirms #247 in the dapp. - LT-00-04 gas presets (#204): PASS. The Low/Medium/High selector is wired into the broadcast — decoded the placement hooks and the per-order max_adjust_steps changes with the preset (Low = 32, higher = 128), i.e. the #260 adaptive floor 32 / cap 256 book-walk budget. tx 132D25A2 (order 15). One copy nit worth a look (not a blocker): the preset controls the contract-side walk budget, but the broadcast gas limit (gasLimitForLimitOrderBatch) scales with rung count only, so the tx is always funded for the worst case. Result: the displayed "Est. network fee: ~22.09 LUNC" is identical across all three presets and both single-order placements broadcast at gasWanted 580,000. The helper text "Uses less gas / Uses more gas" reads as a cost difference that the UI never shows — it's really a reliability control (succeed on deep books), so the copy is slightly misleading. P3. - LT-00-07 deep order book pagination: PASS. Seeded the ask side to 39 resting rungs (prices to ~1.80); the dapp order book pages on scroll (infinite query, has_more honored), prices ascend cleanly, no crash/flicker/dupes. API page1 limit 20 -> 20 orders has_more=true. - TR-00-07 responsive trade layout: PASS (iPad/desktop-narrow, panels stack and stay reachable, no overlap). Checklist moves to PASS: TR-00-03, TR-00-04, TR-00-07, LT-00-04, LT-00-07. New tally: 87 PASS / 6 defer / 1 fail (#353) / 41 left (26 functional + 15 LR-00). Remaining functional: WL matrix (7), ERR-00-01/02/03, RES-00-01/02, XBR-00-01/02/03, PERF-00-01/02, CON-00-02/03, REG-00-06/07/08, INT-00-02/06, CFG-00-03, EDGE-00-03/06, INF-00-04. LR-00 still gated on #350/#353/#354/#355. (Note: the live QA stack picked up several new resting asks from my deep-book seed on pair 1 — session test state, clears on the next reset.)
Brouie commented 2026-06-10 06:07:07 +00:00 (Migrated from gitlab.com)

Wallet matrix (WL-00) — laptop, real extensions (Station/Keplr/Cosmostation installed), on-chain cross-checked.

PASS:

  • Cosmostation (extension): connect + sign + gas honored. Real wallet placed a limit order via the dapp ticket — tx 4CE12F12, sender = the Cosmostation account, order 46 ask @1.40, fee gas 580,000 = 16,428,500 uluna exactly (the dapp's computed gas, honored by the wallet). This is the same suggestChain path Keplr uses (SUGGEST_CHAIN_WALLETS = [KEPLR, COSMOSTATION]), so it proves the dapp's extension connect/sign/gas path end to end.
  • WL-00-04 not-installed UX: PASS. Disabled the Keplr extension, reopened the modal — Keplr row shows a single dimmed "Install" affordance, no duplicate "Not installed" badge (#160).
  • WL-00-06 reject recovery: PASS. Rejected the wallet popup -> "Transaction rejected by user", UI returned to ready, button re-enabled, no stuck pending.
  • WL-00-07 Leap absent: PASS. Wallet list = Simulated, Station, Keplr, Cosmostation, LuncDash, Galaxy Station — Leap correctly not listed (#159).

Documented limitations (not dApp regressions, per the row criteria):

  • WL-00-02 Station on LocalTerra: connect fails. New Station rejects experimentalSuggestChain for localterra (#207) and the addNetwork path needs the LocalTerra network approved in Station; on this setup it never returned a localterra wallet. Per the row, this is the expected Station/LocalTerra fee/signing limitation (#235) — Cosmostation and the Simulated wallet succeed on the same actions, so it is not a dApp regression.
  • WL-00-01 Keplr: blocked at the Keplr layer, not the dapp. After funding the Keplr account, the placement tx built correctly (sender = the Keplr address terra17ks...vx0wnt, accountNumber resolved from chain, and the dapp's gas pushed through: gasLimit 200000 = BASE_GAS_LIMIT for the allowance leg). But Keplr's own balance query to localterra fails ("failed to fetch balance"), so Keplr greys out Approve and the tx cannot be signed. This is the known Keplr-LocalTerra chain-config issue (#127) — Keplr-side, not the dApp. Cosmostation (same code path) is the passing real-extension proxy.

Deferred:

  • WL-00-05 WalletConnect (Cosmostation mobile): QR renders (confirmed via the Galaxy Station WC entry — the QR flow initiates cleanly), but no mobile device on hand to scan/approve/disconnect. Deferred, with QR-render as partial evidence — not a fail.

Minor positive: LuncDash returns a clean "localterra not supported" message (graceful failure, no crash) when its network does not match.

Updated tally: 90 PASS / 8 defer (incl WL-00-01 Keplr-blocked + WL-00-05 no-device) / 1 fail (SW-00-03 / #353) / 36 left = 21 functional + 15 LR-00. Functional remaining: ERR-00-01/02/03, RES-00-01/02, XBR-00-01/02/03, PERF-00-01/02, CON-00-02/03, REG-00-06/07/08, INT-00-02/06, CFG-00-03, EDGE-00-03/06, INF-00-04. LR-00 still gated on #350/#353/#354/#355.

Wallet matrix (WL-00) — laptop, real extensions (Station/Keplr/Cosmostation installed), on-chain cross-checked. PASS: - Cosmostation (extension): connect + sign + gas honored. Real wallet placed a limit order via the dapp ticket — tx 4CE12F12, sender = the Cosmostation account, order 46 ask @1.40, fee gas 580,000 = 16,428,500 uluna exactly (the dapp's computed gas, honored by the wallet). This is the same suggestChain path Keplr uses (SUGGEST_CHAIN_WALLETS = [KEPLR, COSMOSTATION]), so it proves the dapp's extension connect/sign/gas path end to end. - WL-00-04 not-installed UX: PASS. Disabled the Keplr extension, reopened the modal — Keplr row shows a single dimmed "Install" affordance, no duplicate "Not installed" badge (#160). - WL-00-06 reject recovery: PASS. Rejected the wallet popup -> "Transaction rejected by user", UI returned to ready, button re-enabled, no stuck pending. - WL-00-07 Leap absent: PASS. Wallet list = Simulated, Station, Keplr, Cosmostation, LuncDash, Galaxy Station — Leap correctly not listed (#159). Documented limitations (not dApp regressions, per the row criteria): - WL-00-02 Station on LocalTerra: connect fails. New Station rejects experimentalSuggestChain for localterra (#207) and the addNetwork path needs the LocalTerra network approved in Station; on this setup it never returned a localterra wallet. Per the row, this is the expected Station/LocalTerra fee/signing limitation (#235) — Cosmostation and the Simulated wallet succeed on the same actions, so it is not a dApp regression. - WL-00-01 Keplr: blocked at the Keplr layer, not the dapp. After funding the Keplr account, the placement tx built correctly (sender = the Keplr address terra17ks...vx0wnt, accountNumber resolved from chain, and the dapp's gas pushed through: gasLimit 200000 = BASE_GAS_LIMIT for the allowance leg). But Keplr's own balance query to localterra fails ("failed to fetch balance"), so Keplr greys out Approve and the tx cannot be signed. This is the known Keplr-LocalTerra chain-config issue (#127) — Keplr-side, not the dApp. Cosmostation (same code path) is the passing real-extension proxy. Deferred: - WL-00-05 WalletConnect (Cosmostation mobile): QR renders (confirmed via the Galaxy Station WC entry — the QR flow initiates cleanly), but no mobile device on hand to scan/approve/disconnect. Deferred, with QR-render as partial evidence — not a fail. Minor positive: LuncDash returns a clean "localterra not supported" message (graceful failure, no crash) when its network does not match. Updated tally: 90 PASS / 8 defer (incl WL-00-01 Keplr-blocked + WL-00-05 no-device) / 1 fail (SW-00-03 / #353) / 36 left = 21 functional + 15 LR-00. Functional remaining: ERR-00-01/02/03, RES-00-01/02, XBR-00-01/02/03, PERF-00-01/02, CON-00-02/03, REG-00-06/07/08, INT-00-02/06, CFG-00-03, EDGE-00-03/06, INF-00-04. LR-00 still gated on #350/#353/#354/#355.
Brouie commented 2026-06-10 06:17:24 +00:00 (Migrated from gitlab.com)

VPS-side batch (no browser needed) — knocked out the rows verifiable on the QA stack directly.

PASS:

  • INF-00-04 postgres/migrations: DATABASE_URL uses cl8y_legal (not legacy postgres-only), role has LOGIN/SUPERUSER/CREATEDB, 21 migrations applied (latest 20260609140000 = #344). Indexer security integration suite (cargo test --test security) 22/0.
  • CFG-00-03 dev-mnemonic prod guard: full dev mnemonic is NOT present in the production build artifact, and the vite.config.ts guard correctly fails the build (exit 1) when VITE_DEV_MNEMONIC is set in a production build ("must not be set for production builds … GitLab #118"). Dev wallet code is gated behind the build-time DEV_MODE=false constant. (Simulated-Wallet-visible-in-dev has been exercised all session.)
  • EDGE-00-03 non-whitelisted route: GET /api/v1/route/solve returns 400 for a malformed token_in and 400 "token_in not found in indexer assets" for a well-formed but unlisted token — graceful, no crash.
  • INT-00-02 reserves consistency: LCD pool{} reserves {96863935727, 95461641693} match the indexer pair_reserves row exactly. (UI reads the indexer; visual confirm rides the next browser pass.)
  • INT-00-06 QA tunnel workflow: qa-tunnel-help target present; this whole browser pass is the tunnel workflow in use (laptop dapp -> tunneled LCD/RPC/indexer, real swaps landing).
  • REG-00-08 issue verifiers: verify-issue-285 exit 0 (4/4 live — limit_order_fill attribution scoped by _contract_address), verify-issue-324 exit 0 (3/3 — concurrent_solve + hybrid_cache_key + route_solve_get_cache).

Caveat on REG-00-08 / verify-issue-293: exits 1, but NOT a #293 regression. The #293 core check (OE-1 hub pairs pool_only near-inverse) PASSES; the four failures are all the swarm liquidity bootstrap (make swarm-bootstrap-liquidity / swarm-launch) dying on chmod: Operation not permitted against root-owned scripts/bots/*.sh — the same no-sudo box constraint that affects start-qa. The route-asymmetry and slippage-enrichment sub-checks fail downstream because the balanced swarm liquidity never got bootstrapped, not because the feature regressed. #293 was verified exit 0 (8/0) on this same 038a457 stack on 2026-06-07. Full re-run needs a clean host (or sudo to chmod the bot scripts) — deferring that rather than launching a full swarm mid-session. verify-issue-295 is the Playwright/laptop piece, batched with the e2e rows.

The make wrappers for these verifiers also tripped the same root-owned-script chmod (Makefile @chmod step) — ran the scripts directly via bash to get the live results.

Tally: 96 PASS / 8 defer / 1 fail (#353) / 30 left. The 30 left = 15 functional (all browser/Playwright on laptop: ERR-00-01/02/03, RES-00-01/02, XBR-00-01/02/03, PERF-00-01/02, CON-00-02/03, REG-00-06/07, EDGE-00-06) + 15 LR-00. VPS-side queue is now exhausted. LR-00 still gated on #350/#353/#354/#355.

VPS-side batch (no browser needed) — knocked out the rows verifiable on the QA stack directly. PASS: - INF-00-04 postgres/migrations: DATABASE_URL uses cl8y_legal (not legacy postgres-only), role has LOGIN/SUPERUSER/CREATEDB, 21 migrations applied (latest 20260609140000 = #344). Indexer security integration suite (cargo test --test security) 22/0. - CFG-00-03 dev-mnemonic prod guard: full dev mnemonic is NOT present in the production build artifact, and the vite.config.ts guard correctly fails the build (exit 1) when VITE_DEV_MNEMONIC is set in a production build ("must not be set for production builds … GitLab #118"). Dev wallet code is gated behind the build-time DEV_MODE=false constant. (Simulated-Wallet-visible-in-dev has been exercised all session.) - EDGE-00-03 non-whitelisted route: GET /api/v1/route/solve returns 400 for a malformed token_in and 400 "token_in not found in indexer assets" for a well-formed but unlisted token — graceful, no crash. - INT-00-02 reserves consistency: LCD pool{} reserves {96863935727, 95461641693} match the indexer pair_reserves row exactly. (UI reads the indexer; visual confirm rides the next browser pass.) - INT-00-06 QA tunnel workflow: qa-tunnel-help target present; this whole browser pass is the tunnel workflow in use (laptop dapp -> tunneled LCD/RPC/indexer, real swaps landing). - REG-00-08 issue verifiers: verify-issue-285 exit 0 (4/4 live — limit_order_fill attribution scoped by _contract_address), verify-issue-324 exit 0 (3/3 — concurrent_solve + hybrid_cache_key + route_solve_get_cache). Caveat on REG-00-08 / verify-issue-293: exits 1, but NOT a #293 regression. The #293 core check (OE-1 hub pairs pool_only near-inverse) PASSES; the four failures are all the swarm liquidity bootstrap (make swarm-bootstrap-liquidity / swarm-launch) dying on `chmod: Operation not permitted` against root-owned scripts/bots/*.sh — the same no-sudo box constraint that affects start-qa. The route-asymmetry and slippage-enrichment sub-checks fail downstream because the balanced swarm liquidity never got bootstrapped, not because the feature regressed. #293 was verified exit 0 (8/0) on this same 038a457 stack on 2026-06-07. Full re-run needs a clean host (or sudo to chmod the bot scripts) — deferring that rather than launching a full swarm mid-session. verify-issue-295 is the Playwright/laptop piece, batched with the e2e rows. The make wrappers for these verifiers also tripped the same root-owned-script chmod (Makefile @chmod step) — ran the scripts directly via bash to get the live results. Tally: 96 PASS / 8 defer / 1 fail (#353) / 30 left. The 30 left = 15 functional (all browser/Playwright on laptop: ERR-00-01/02/03, RES-00-01/02, XBR-00-01/02/03, PERF-00-01/02, CON-00-02/03, REG-00-06/07, EDGE-00-06) + 15 LR-00. VPS-side queue is now exhausted. LR-00 still gated on #350/#353/#354/#355.
Brouie commented 2026-06-10 06:51:02 +00:00 (Migrated from gitlab.com)

mentioned in issue #357

mentioned in issue #357
Brouie commented 2026-06-11 02:12:51 +00:00 (Migrated from gitlab.com)

Main-tree health findings while verifying the #356/#357 wave at 3169af0 — three things, all slipping past CI. Fixes for the first two are ready and going up as small MRs.

  1. npm run build is red on main: tsc -b fails with TS7006 in tradePairPrefetch.ts:43 (getNextPageParam param implicitly any). Came in with 35e38e5, the #354 prefetchInfiniteQuery fix. Reproduces in a clean tree at e198dcb and 3169af0. One-line fix: type the param as IndexerLimitBookPageResponse — build green, dist clean of sourcemaps, both prefetch regression files pass (3+1). This is the third tsc-only break to slip through (#246, then the one I fixed in !834) — the pipeline runs vitest+eslint but never tsc -b.

  2. SwapPage.test.tsx carries 2 red tests on main — the #293 expert-mode slippage block and the #329 fallback-label one. Bisected both to the same commit: 76723cf (the #341 preflight fix, merged in a6c43ca) added an enrichSwapOperationsWithHopMinReturns call to the quote path, but the suite's vi.mock factory for swapRoutePreflight never exported that function — undefined under the mock, throws inside the try, gets caught as an indexer failure, and the quote path dies. Test-bug only, no product regression: patching just the mock at e198dcb turns both tests green, and the real function on the live path is fine (the #341 behavior itself verified earlier). Fix = one mock export; the file runs 11/11 with it.

  3. Why CI never noticed either one: besides the missing tsc step, the recent main pipelines only ran the qa-indexer-binary job (itself red), so the frontend vitest job hasn't actually exercised main lately.

@PlasticDigits flagging the CI gap for your call — a tsc -b (or full npm run build) step plus making the frontend vitest job run on main pushes would have caught two of these three before they landed.

Main-tree health findings while verifying the #356/#357 wave at 3169af0 — three things, all slipping past CI. Fixes for the first two are ready and going up as small MRs. 1. npm run build is red on main: tsc -b fails with TS7006 in tradePairPrefetch.ts:43 (getNextPageParam param implicitly any). Came in with 35e38e5, the #354 prefetchInfiniteQuery fix. Reproduces in a clean tree at e198dcb and 3169af0. One-line fix: type the param as IndexerLimitBookPageResponse — build green, dist clean of sourcemaps, both prefetch regression files pass (3+1). This is the third tsc-only break to slip through (#246, then the one I fixed in !834) — the pipeline runs vitest+eslint but never tsc -b. 2. SwapPage.test.tsx carries 2 red tests on main — the #293 expert-mode slippage block and the #329 fallback-label one. Bisected both to the same commit: 76723cf (the #341 preflight fix, merged in a6c43ca) added an enrichSwapOperationsWithHopMinReturns call to the quote path, but the suite's vi.mock factory for swapRoutePreflight never exported that function — undefined under the mock, throws inside the try, gets caught as an indexer failure, and the quote path dies. Test-bug only, no product regression: patching just the mock at e198dcb turns both tests green, and the real function on the live path is fine (the #341 behavior itself verified earlier). Fix = one mock export; the file runs 11/11 with it. 3. Why CI never noticed either one: besides the missing tsc step, the recent main pipelines only ran the qa-indexer-binary job (itself red), so the frontend vitest job hasn't actually exercised main lately. @PlasticDigits flagging the CI gap for your call — a tsc -b (or full npm run build) step plus making the frontend vitest job run on main pushes would have caught two of these three before they landed.
Brouie commented 2026-06-11 02:14:11 +00:00 (Migrated from gitlab.com)

mentioned in merge request !863

mentioned in merge request !863
Brouie commented 2026-06-11 02:14:24 +00:00 (Migrated from gitlab.com)

mentioned in merge request !864

mentioned in merge request !864
Brouie commented 2026-06-11 03:46:52 +00:00 (Migrated from gitlab.com)

mentioned in issue #359

mentioned in issue #359
Brouie commented 2026-06-11 04:58:09 +00:00 (Migrated from gitlab.com)

Batch wrap + LR-00-15 status comment in one. Scenario tally after tonight: 106 PASS / 1 FAIL / 13 DEFER of 120; LR-00 7 PASS / 5 PARTIAL / 3 BLOCKED of 15. Template first, evidence under it.

Build: 3169af0 (frontend/indexer tree; deployed chain stamp 038a457 — zero contract-source diff since)
Environment: QA server stack, laptop Chrome over SSH tunnel
Launch mode: pool-only focus; hybrid rows exercised where in scope (book-hybrid swap live-verified)
Wallet coverage: Simulated (test1), Cosmostation extension (real signing path). Keplr blocked by #127 (extension-side; Cosmostation = same-path proxy). Station documented #207/#235. WalletConnect QR renders, no mobile device. Leap correctly absent (#159). No Firefox on test hardware (XBR-00-02 deferred).
REG suite: PARTIAL — REG-00-01/03/04/05/08/09/10 PASS; REG-00-02 RED on main (stale-mock failures, fix !864 open); REG-00-06/07 + XBR-00-03 + CON-00-02 + verify-295 DEFERRED to a clean-host agent run (harness needs a local docker stack; fixtures already seeded chain-side)
LR-00 checklist: 7/15 PASS (01,03,05,06,09,12,15), 5 PARTIAL (04,07,11,13,14), 3 BLOCKED (02 on !863/!864 + e2e run; 08 on !863; 10 on open blockers)
Open blockers: #353 2-hop gas short (3x live OOG), #358 deep-link notice wipe, #359 broadcast-retry double-execution; !863 (tsc build) + !864 (unit tests) awaiting merge; #356/#357 verified, awaiting close
Tester: @Brouie
Date: 2026-06-11

Tonight's evidence (laptop Chrome + Cosmostation/Simulated, on-chain cross-checked from the indexer/LCD side):

PASS:

  • SW-00-03 wrap half: native LUNC -> EMBER wrap-swap tx 28EA7D0F, code 0, gas 1,534,413/1,800,000 — !854 wrap+router budget holds (old 1.14M would have OOG'd).
  • ERR-00-01: chain stopped live mid-quote — honest banner naming network + LCD endpoint, Retry + auto-reconnect, balance blanks to em-dash, no white screen; quotes resumed on restore without reload.
  • ERR-00-03: RPC frozen between sign and broadcast — actionable failure copy, UI recovers. Surfaced #359 (copy invites retry while the signed tx still landed = double-execution risk; tx 36324C8C reconciled on-chain).
  • ERR-00-02 + EDGE-00-06: offline lazy-chunk load -> "Page unavailable" recovery UI with Try Again inside an intact shell; retry loads clean once back online.
  • RES-00-01 mobile 390px nav all routes incl. More sheet; RES-00-02 tablet 768px limit ticket with live round-trip (order 47 ask@1.2 tx 24A8FD16, cancel CC63048F, escrow reconciled, indexer cancellation row).
  • CON-00-03 two-tab quote consistency (identical 4.838 both tabs). XBR-00-01 rides every Chrome row.
  • PERF-00-01: route-solve p50 17ms / p95 20ms / max 82ms over 20 varied-amount calls at the service layer — 1s gate clears 50x. (Browser-side number through an SSH tunnel isn't representative; rides the agent run.)
  • PERF-00-02: /trade soaked ~2h this session, JS heap 263MB -> 275MB early then stable in use, no runaway, tab healthy throughout. Formal snapshot diff not captured — noting the basis honestly.

FAIL (open):

  • SW-00-03 2-hop half: three code-11 txs at the recalibrated 1,810,000 budget — gasUsed 1,810,073 / 1,810,138 / 1,810,003 (cold-balance receiver EMBER->JADE->RUBY). Evidence + fix suggestion on #353.

DEFER:

  • XBR-00-02 (no Firefox on hardware).
  • REG-00-06/07, XBR-00-03, CON-00-02, verify-295: e2e harness provisions through a local docker stack; test hardware cannot carry it. Chain-side fixtures are ALREADY provisioned (dev wallet topped up, hybrid book head order, wrap pairs indexed) so a clean-host agent run picks these up directly. @PlasticDigits — requesting that run at current main, ideally after !863/!864 merge so REG-00-02 and the build gate flip in the same pass. That run + the blocker fixes are what stand between 7/15 and the final LR-00 sign-off.

Also live-observed along the way: route-solve fidelity (global_v4 EMBER->JADE->RUBY at ~217x the client-BFS fallback output), the #341 hop-spread guard correctly blocking a 32% thin-pool hop at 0.5% tolerance, and the #330 degrade banner truthfully reporting a real tunnel drop.

Batch wrap + LR-00-15 status comment in one. Scenario tally after tonight: 106 PASS / 1 FAIL / 13 DEFER of 120; LR-00 7 PASS / 5 PARTIAL / 3 BLOCKED of 15. Template first, evidence under it. ``` Build: 3169af0 (frontend/indexer tree; deployed chain stamp 038a457 — zero contract-source diff since) Environment: QA server stack, laptop Chrome over SSH tunnel Launch mode: pool-only focus; hybrid rows exercised where in scope (book-hybrid swap live-verified) Wallet coverage: Simulated (test1), Cosmostation extension (real signing path). Keplr blocked by #127 (extension-side; Cosmostation = same-path proxy). Station documented #207/#235. WalletConnect QR renders, no mobile device. Leap correctly absent (#159). No Firefox on test hardware (XBR-00-02 deferred). REG suite: PARTIAL — REG-00-01/03/04/05/08/09/10 PASS; REG-00-02 RED on main (stale-mock failures, fix !864 open); REG-00-06/07 + XBR-00-03 + CON-00-02 + verify-295 DEFERRED to a clean-host agent run (harness needs a local docker stack; fixtures already seeded chain-side) LR-00 checklist: 7/15 PASS (01,03,05,06,09,12,15), 5 PARTIAL (04,07,11,13,14), 3 BLOCKED (02 on !863/!864 + e2e run; 08 on !863; 10 on open blockers) Open blockers: #353 2-hop gas short (3x live OOG), #358 deep-link notice wipe, #359 broadcast-retry double-execution; !863 (tsc build) + !864 (unit tests) awaiting merge; #356/#357 verified, awaiting close Tester: @Brouie Date: 2026-06-11 ``` Tonight's evidence (laptop Chrome + Cosmostation/Simulated, on-chain cross-checked from the indexer/LCD side): PASS: - SW-00-03 wrap half: native LUNC -> EMBER wrap-swap tx 28EA7D0F, code 0, gas 1,534,413/1,800,000 — !854 wrap+router budget holds (old 1.14M would have OOG'd). - ERR-00-01: chain stopped live mid-quote — honest banner naming network + LCD endpoint, Retry + auto-reconnect, balance blanks to em-dash, no white screen; quotes resumed on restore without reload. - ERR-00-03: RPC frozen between sign and broadcast — actionable failure copy, UI recovers. Surfaced #359 (copy invites retry while the signed tx still landed = double-execution risk; tx 36324C8C reconciled on-chain). - ERR-00-02 + EDGE-00-06: offline lazy-chunk load -> "Page unavailable" recovery UI with Try Again inside an intact shell; retry loads clean once back online. - RES-00-01 mobile 390px nav all routes incl. More sheet; RES-00-02 tablet 768px limit ticket with live round-trip (order 47 ask@1.2 tx 24A8FD16, cancel CC63048F, escrow reconciled, indexer cancellation row). - CON-00-03 two-tab quote consistency (identical 4.838 both tabs). XBR-00-01 rides every Chrome row. - PERF-00-01: route-solve p50 17ms / p95 20ms / max 82ms over 20 varied-amount calls at the service layer — 1s gate clears 50x. (Browser-side number through an SSH tunnel isn't representative; rides the agent run.) - PERF-00-02: /trade soaked ~2h this session, JS heap 263MB -> 275MB early then stable in use, no runaway, tab healthy throughout. Formal snapshot diff not captured — noting the basis honestly. FAIL (open): - SW-00-03 2-hop half: three code-11 txs at the recalibrated 1,810,000 budget — gasUsed 1,810,073 / 1,810,138 / 1,810,003 (cold-balance receiver EMBER->JADE->RUBY). Evidence + fix suggestion on #353. DEFER: - XBR-00-02 (no Firefox on hardware). - REG-00-06/07, XBR-00-03, CON-00-02, verify-295: e2e harness provisions through a local docker stack; test hardware cannot carry it. Chain-side fixtures are ALREADY provisioned (dev wallet topped up, hybrid book head order, wrap pairs indexed) so a clean-host agent run picks these up directly. @PlasticDigits — requesting that run at current main, ideally after !863/!864 merge so REG-00-02 and the build gate flip in the same pass. That run + the blocker fixes are what stand between 7/15 and the final LR-00 sign-off. Also live-observed along the way: route-solve fidelity (global_v4 EMBER->JADE->RUBY at ~217x the client-BFS fallback output), the #341 hop-spread guard correctly blocking a 32% thin-pool hop at 0.5% tolerance, and the #330 degrade banner truthfully reporting a real tunnel drop.
Brouie commented 2026-06-12 03:50:52 +00:00 (Migrated from gitlab.com)

Status update at main 16e0656 (chain stamp still 038a457 — zero contract-source diff in the range; this wave was frontend + cloud-agent infra + docs only). Big movement on the blocker set since the last tally.

Board flips (all P0/P1 from the last note are gone):

  • #350 / #353 / #354 / #355 / #357 all CLOSED. No open issue carries a blocker label anymore — LR-00-10 gate is CLEAR for pool-only (was BLOCKED on exactly those four).
  • #356 / #357 verified and closed. #358 (deep-link notice wipe) and #360 (#356 hybrid-submit follow-up) shipped and verified by me at the source+unit layer with pre-fix proofs — notes on each. #359 (broadcast-retry double-execution) fix is up in !867, not yet merged.
  • SW-00-03 2-hop OOG: #353 is closed (gas fix shipped), so the one open scenario FAIL is resolved at the source — needs one laptop re-broadcast EMBER->RUBY to flip the row green.

Fresh on the VPS at 16e0656 (the rows the frontend wave actually touched):

  • REG-00-02 frontend: build green and vitest 935/937 — the 2 fails are the known terraExplorer 127.0.0.1-vs-localhost env artifact, not a regression. NOTE: #360's merge left npm run build (tsc -b) red again; one-line fix is up as !868, build is green with it. So REG-00-02 + the build gate are green once !868 merges (same CI gap — no tsc -b in the pipeline).
  • PERF-00-03: dist ships 0 sourcemaps (#117 holds).
  • REG-00-09 fee-tier doc drift: OK, 11 tiers aligned.
  • REG-00-10 lint-frontend: exit 0 (5 pre-existing exhaustive-deps warnings, none in the changed files).
  • Backend REG gates (REG-00-01 contracts, -03 indexer lib, -04 integration, -05 charts, -08 verify-285/293/324): carried green from the last run on the identical tree — zero source diff in the range and disk is at 92%, so I did not rebuild them this session. Flag if you want a fresh re-run.

LR-00 re-tally: 9 PASS / 6 PARTIAL / 0 BLOCKED (was 7 / 5 / 3).

  • PASS: 01, 03, 05, 06, 08 (SEC-00-04/05 + PERF-00-03, was blocked on the build), 09, 10 (no open blockers), 12, 15.
  • PARTIAL, all reducing to two actions below: 02 (non-e2e REG green; e2e rows pending), 04 (wallet — Keplr blocked by #127 extension-side, no WC mobile device), 07 (degraded mode green except the outage e2e), 11 (#292 reset-qa + e2e), 13 (fee-doc check green; runbook operator confirm is yours), 14 (RES-00-01 green; Playwright pending).
  • BLOCKED: none.

What's actually left, and where it has to run:

  1. Clean-host agent e2e run at 16e0656: REG-00-06/07, XBR-00-03, CON-00-02, verify-295. Flips LR-00-02/07/11/14. Test hardware here can't carry the docker+Playwright stack and the VPS is barred by the no-frontend rule; chain-side fixtures are already seeded. @PlasticDigits requesting that run at current main, ideally after !868 + !867 merge so the build/REG-00-02 gate flips in the same pass.
  2. Laptop browser final LR re-confirm at 16e0656: the LR PASS rows above were browser-verified on earlier SHAs, so they want a re-confirm on the final frontend build, plus the live checks for #358 / #359 / #360 and the #353 2-hop re-broadcast, plus the wallet matrix. On my queue.

So: 0 blockers open, the VPS share is current at 16e0656, and the gap to the 15/15 LR sign-off is the one clean-host e2e run plus the laptop browser re-confirm — gated on !868 and !867 landing. @PlasticDigits the two merges + that agent run are the path to sign-off.

Status update at main 16e0656 (chain stamp still 038a457 — zero contract-source diff in the range; this wave was frontend + cloud-agent infra + docs only). Big movement on the blocker set since the last tally. Board flips (all P0/P1 from the last note are gone): - #350 / #353 / #354 / #355 / #357 all CLOSED. No open issue carries a blocker label anymore — LR-00-10 gate is CLEAR for pool-only (was BLOCKED on exactly those four). - #356 / #357 verified and closed. #358 (deep-link notice wipe) and #360 (#356 hybrid-submit follow-up) shipped and verified by me at the source+unit layer with pre-fix proofs — notes on each. #359 (broadcast-retry double-execution) fix is up in !867, not yet merged. - SW-00-03 2-hop OOG: #353 is closed (gas fix shipped), so the one open scenario FAIL is resolved at the source — needs one laptop re-broadcast EMBER->RUBY to flip the row green. Fresh on the VPS at 16e0656 (the rows the frontend wave actually touched): - REG-00-02 frontend: build green and vitest 935/937 — the 2 fails are the known terraExplorer 127.0.0.1-vs-localhost env artifact, not a regression. NOTE: #360's merge left npm run build (tsc -b) red again; one-line fix is up as !868, build is green with it. So REG-00-02 + the build gate are green once !868 merges (same CI gap — no tsc -b in the pipeline). - PERF-00-03: dist ships 0 sourcemaps (#117 holds). - REG-00-09 fee-tier doc drift: OK, 11 tiers aligned. - REG-00-10 lint-frontend: exit 0 (5 pre-existing exhaustive-deps warnings, none in the changed files). - Backend REG gates (REG-00-01 contracts, -03 indexer lib, -04 integration, -05 charts, -08 verify-285/293/324): carried green from the last run on the identical tree — zero source diff in the range and disk is at 92%, so I did not rebuild them this session. Flag if you want a fresh re-run. LR-00 re-tally: 9 PASS / 6 PARTIAL / 0 BLOCKED (was 7 / 5 / 3). - PASS: 01, 03, 05, 06, 08 (SEC-00-04/05 + PERF-00-03, was blocked on the build), 09, 10 (no open blockers), 12, 15. - PARTIAL, all reducing to two actions below: 02 (non-e2e REG green; e2e rows pending), 04 (wallet — Keplr blocked by #127 extension-side, no WC mobile device), 07 (degraded mode green except the outage e2e), 11 (#292 reset-qa + e2e), 13 (fee-doc check green; runbook operator confirm is yours), 14 (RES-00-01 green; Playwright pending). - BLOCKED: none. What's actually left, and where it has to run: 1. Clean-host agent e2e run at 16e0656: REG-00-06/07, XBR-00-03, CON-00-02, verify-295. Flips LR-00-02/07/11/14. Test hardware here can't carry the docker+Playwright stack and the VPS is barred by the no-frontend rule; chain-side fixtures are already seeded. @PlasticDigits requesting that run at current main, ideally after !868 + !867 merge so the build/REG-00-02 gate flips in the same pass. 2. Laptop browser final LR re-confirm at 16e0656: the LR PASS rows above were browser-verified on earlier SHAs, so they want a re-confirm on the final frontend build, plus the live checks for #358 / #359 / #360 and the #353 2-hop re-broadcast, plus the wallet matrix. On my queue. So: 0 blockers open, the VPS share is current at 16e0656, and the gap to the 15/15 LR sign-off is the one clean-host e2e run plus the laptop browser re-confirm — gated on !868 and !867 landing. @PlasticDigits the two merges + that agent run are the path to sign-off.
Brouie commented 2026-06-12 04:52:51 +00:00 (Migrated from gitlab.com)

Correction + a new wrinkle on the build gate. Earlier today I called npm run build green at the !868 SHA — that was an incremental-cache false negative. A clean build (fresh .tsbuildinfo, like CI or a fresh checkout) is RED on main 8408689 with 3 type-only errors, all in files the #359 merge (cd17813 / !867) added:

  • terraTxHash.ts:6 — toBinary() Uint8Array vs crypto.subtle.digest BufferSource (TS 5.9 lib)
  • terraWalletSignTxRaw.ts:109 — dev MnemonicWallet id 'mnemonic' is outside the cosmes WalletName enum (no-overlap comparison)
  • terraWalletSignTxRaw.ts:116 — ConnectedWallet.sequence is private, blocking the cast

typescript 5.9.3 and @types/node 22.19.15 are both lockfile-pinned, so CI hits these exactly — not a local float. An incremental tsc -b with a warm cache skips the unchanged files and masks all three, which is why it slipped past the merge AND my earlier check.

Fix up in !870 (type-only, no runtime change). Clean npm run build green after it, full vitest 594/596 (the 2 = the known terraExplorer 127.0.0.1-vs-localhost env artifact).

@PlasticDigits this is the 4th tsc-only break on main. The CI gap is now two-layered: the pipeline never runs tsc -b at all, and even when it's run locally an incremental build can hide a break. A tsc -b (or npm run build) step that runs cache-cold would catch this whole class. Net for #337: REG-00-02 / the build half of LR-00-02/08 are green only with !868 + !870 both merged.

Correction + a new wrinkle on the build gate. Earlier today I called npm run build green at the !868 SHA — that was an incremental-cache false negative. A clean build (fresh .tsbuildinfo, like CI or a fresh checkout) is RED on main 8408689 with 3 type-only errors, all in files the #359 merge (cd17813 / !867) added: - terraTxHash.ts:6 — toBinary() Uint8Array<ArrayBufferLike> vs crypto.subtle.digest BufferSource (TS 5.9 lib) - terraWalletSignTxRaw.ts:109 — dev MnemonicWallet id 'mnemonic' is outside the cosmes WalletName enum (no-overlap comparison) - terraWalletSignTxRaw.ts:116 — ConnectedWallet.sequence is private, blocking the cast typescript 5.9.3 and @types/node 22.19.15 are both lockfile-pinned, so CI hits these exactly — not a local float. An incremental tsc -b with a warm cache skips the unchanged files and masks all three, which is why it slipped past the merge AND my earlier check. Fix up in !870 (type-only, no runtime change). Clean npm run build green after it, full vitest 594/596 (the 2 = the known terraExplorer 127.0.0.1-vs-localhost env artifact). @PlasticDigits this is the 4th tsc-only break on main. The CI gap is now two-layered: the pipeline never runs tsc -b at all, and even when it's run locally an incremental build can hide a break. A tsc -b (or npm run build) step that runs cache-cold would catch this whole class. Net for #337: REG-00-02 / the build half of LR-00-02/08 are green only with !868 + !870 both merged.
Brouie commented 2026-06-12 05:56:14 +00:00 (Migrated from gitlab.com)

mentioned in issue #369

mentioned in issue #369
Brouie commented 2026-06-12 06:16:25 +00:00 (Migrated from gitlab.com)

LR-00-15 status snapshot after tonight's laptop pass (not the final sign-off — gated items listed under Open blockers).

Build: 8408689 (frontend/indexer tree; deployed chain stamp 038a457, no contract-source diff)
Environment: QA server stack, laptop Chrome over SSH tunnel
Launch mode: pool-only focus; hybrid rows exercised (book-hybrid submit on-chain match verified)
Wallet coverage: Simulated (test1), Cosmostation extension (real signing path). Keplr blocked by #127 (extension-side; Cosmostation = same-path proxy). Station documented #207/#235. WalletConnect QR renders, no mobile device. Leap absent (#159). No Firefox (XBR-00-02 deferred).
REG suite: PARTIAL - non-e2e gates green once !869 + !870 merge (build/REG-00-02 need !870; 2-hop gas in !869); REG-00-06/07 + XBR-00-03 + CON-00-02 + verify-295 deferred to clean-host agent run
LR-00 checklist: 6/15 PASS (01, 03, 04, 05, 10, 12); rest PARTIAL pending merges + clean-host e2e + #369
Open blockers: SW-00-03 2-hop OOG (FAIL until !869 merges + re-broadcast); #369 route/solve mirror-sim 502; !869 + !870 unmerged; #353 needs reopen
Tester: @Brouie
Date: 2026-06-12

Verified tonight (browser, on-chain cross-checked):

  • #354 click-switch: PASS (no ErrorBoundary crash).
  • SW-00-01 direct swap: PASS, tx 1D82DB21 code 0, gas 624k/840k.
  • #358 deep-link notices: PASS - unknown + invalid links park at /trade with the notice, no snap to default.
  • #360 hybrid submit snapshot: PASS - tx 92F7393E carries pool_input 8000000 / book_input 2000000 / max_maker_fills 8 / min_return 9.697 exactly matching the displayed quote; stale gate observed live.
  • #359 broadcast recovery: PASS (unreachable-RPC path) - froze chain mid-broadcast, dapp showed "Checking connection..." recovery poll, signed tx did NOT land (zero orphans), Retry produced exactly ONE swap D8593B5D code 0. No double-spend. Residual: broadcast-accepted-but-response-lost race needs the ongoing E2E (gap report H12).
  • SEC-00-04 NFA footer: PASS. A11Y keyboard nav (A11Y-00-02): PASS (focus visible, flow completable).

Findings shipped:

  • !869 - router multi-hop gas floor 900k->950k/hop. 2-hop OOG'd at exactly 1,810,000 (3 live code-11, gasUsed 1,810,064-1,810,206). Reopen evidence on #353.
  • !870 - 3 tsc-only errors the #359 merge added; cache-cold npm run build is red on main without it.
  • #369 - route/solve 502s for EMBER<->CORAL despite a healthy direct pool (DB-hybrid mirror sim hard-fails on a zero-reserve candidate pair). Degrades IDX-00-02 + the >30% slippage UX (SEC-00-05/SW-00-04); on-chain swaps unaffected.

@PlasticDigits path to LR-00-15 final: (1) merge !869 + !870, (2) reopen #353 + I re-broadcast the 2-hop, (3) resolve/decide #369, (4) clean-host agent e2e at 8408689 -> flips REG-00-06/07 + XBR-00-03 + CON-00-02 + verify-295 + axe a11y -> LR-00-02/06/07/09/11/14. Chain-side e2e fixtures already seeded.

LR-00-15 status snapshot after tonight's laptop pass (not the final sign-off — gated items listed under Open blockers). ``` Build: 8408689 (frontend/indexer tree; deployed chain stamp 038a457, no contract-source diff) Environment: QA server stack, laptop Chrome over SSH tunnel Launch mode: pool-only focus; hybrid rows exercised (book-hybrid submit on-chain match verified) Wallet coverage: Simulated (test1), Cosmostation extension (real signing path). Keplr blocked by #127 (extension-side; Cosmostation = same-path proxy). Station documented #207/#235. WalletConnect QR renders, no mobile device. Leap absent (#159). No Firefox (XBR-00-02 deferred). REG suite: PARTIAL - non-e2e gates green once !869 + !870 merge (build/REG-00-02 need !870; 2-hop gas in !869); REG-00-06/07 + XBR-00-03 + CON-00-02 + verify-295 deferred to clean-host agent run LR-00 checklist: 6/15 PASS (01, 03, 04, 05, 10, 12); rest PARTIAL pending merges + clean-host e2e + #369 Open blockers: SW-00-03 2-hop OOG (FAIL until !869 merges + re-broadcast); #369 route/solve mirror-sim 502; !869 + !870 unmerged; #353 needs reopen Tester: @Brouie Date: 2026-06-12 ``` Verified tonight (browser, on-chain cross-checked): - #354 click-switch: PASS (no ErrorBoundary crash). - SW-00-01 direct swap: PASS, tx 1D82DB21 code 0, gas 624k/840k. - #358 deep-link notices: PASS - unknown + invalid links park at /trade with the notice, no snap to default. - #360 hybrid submit snapshot: PASS - tx 92F7393E carries pool_input 8000000 / book_input 2000000 / max_maker_fills 8 / min_return 9.697 exactly matching the displayed quote; stale gate observed live. - #359 broadcast recovery: PASS (unreachable-RPC path) - froze chain mid-broadcast, dapp showed "Checking connection..." recovery poll, signed tx did NOT land (zero orphans), Retry produced exactly ONE swap D8593B5D code 0. No double-spend. Residual: broadcast-accepted-but-response-lost race needs the ongoing E2E (gap report H12). - SEC-00-04 NFA footer: PASS. A11Y keyboard nav (A11Y-00-02): PASS (focus visible, flow completable). Findings shipped: - !869 - router multi-hop gas floor 900k->950k/hop. 2-hop OOG'd at exactly 1,810,000 (3 live code-11, gasUsed 1,810,064-1,810,206). Reopen evidence on #353. - !870 - 3 tsc-only errors the #359 merge added; cache-cold npm run build is red on main without it. - #369 - route/solve 502s for EMBER<->CORAL despite a healthy direct pool (DB-hybrid mirror sim hard-fails on a zero-reserve candidate pair). Degrades IDX-00-02 + the >30% slippage UX (SEC-00-05/SW-00-04); on-chain swaps unaffected. @PlasticDigits path to LR-00-15 final: (1) merge !869 + !870, (2) reopen #353 + I re-broadcast the 2-hop, (3) resolve/decide #369, (4) clean-host agent e2e at 8408689 -> flips REG-00-06/07 + XBR-00-03 + CON-00-02 + verify-295 + axe a11y -> LR-00-02/06/07/09/11/14. Chain-side e2e fixtures already seeded.
Brouie commented 2026-06-12 07:34:30 +00:00 (Migrated from gitlab.com)

mentioned in issue #366

mentioned in issue #366
Brouie commented 2026-06-28 22:41:04 +00:00 (Migrated from gitlab.com)

Back on this after the big wave landed — re-baselining the whole checklist against current main (8c56f4b8). Everything LR-00 was gated on (#353/#357/#359/#366/#369 + the !867–!870 MRs) has merged, so the gate now is the redeploy + re-verify, not the fixes.

First thing the source-gate re-run caught: npm run build (tsc -b) is red on main. Two TS2322s, one root cause — SwapAdvancedSettings types bookLegMaxResult as { spendableRaw: string; human: string }, but the value is ComputeMaxSpendableHumanAmountResult where spendableRaw is a bigint. Breaks the prop pass from SwapPage (#417) and the spendableRaw -> AmountBalanceActions bigint prop (#413). Type-only fix up as !951. Same blind spot as the earlier ones — CI runs no tsc -b.

Source gates so far on 8c56f4b8:

  • contracts cargo test 452/0
  • indexer lib 152/0, integration 523/0 (run serial — parallel cargo test races the shared test DB on api_hooks, not a real fail)
  • frontend: tsc red -> !951; vite prod bundle builds clean once the new #378 VITE_WC_PROJECT_ID guard is satisfied; vitest 1082/1084 (the 2 are the known terraExplorer localhost-vs-127.0.0.1 env artifact)

Redeploying the chain now — contracts changed (the #377 hook-settlement rework: pair settles tax/burn itself, min_return floor checks the net payout, lp-burn-hook caller auth), so the live bytecode is stale, and the indexer moved too (#379 hardening). Once it's up I'll re-verify the contract-behavior deltas on-chain plus the carried residuals and refresh the LR rows. Not signing anything off yet — this is a re-baseline.

Back on this after the big wave landed — re-baselining the whole checklist against current main (8c56f4b8). Everything LR-00 was gated on (#353/#357/#359/#366/#369 + the !867–!870 MRs) has merged, so the gate now is the redeploy + re-verify, not the fixes. First thing the source-gate re-run caught: `npm run build` (tsc -b) is red on main. Two TS2322s, one root cause — SwapAdvancedSettings types `bookLegMaxResult` as `{ spendableRaw: string; human: string }`, but the value is `ComputeMaxSpendableHumanAmountResult` where `spendableRaw` is a bigint. Breaks the prop pass from SwapPage (#417) and the `spendableRaw` -> AmountBalanceActions bigint prop (#413). Type-only fix up as !951. Same blind spot as the earlier ones — CI runs no tsc -b. Source gates so far on 8c56f4b8: - contracts cargo test 452/0 - indexer lib 152/0, integration 523/0 (run serial — parallel `cargo test` races the shared test DB on api_hooks, not a real fail) - frontend: tsc red -> !951; vite prod bundle builds clean once the new #378 `VITE_WC_PROJECT_ID` guard is satisfied; vitest 1082/1084 (the 2 are the known terraExplorer localhost-vs-127.0.0.1 env artifact) Redeploying the chain now — contracts changed (the #377 hook-settlement rework: pair settles tax/burn itself, min_return floor checks the net payout, lp-burn-hook caller auth), so the live bytecode is stale, and the indexer moved too (#379 hardening). Once it's up I'll re-verify the contract-behavior deltas on-chain plus the carried residuals and refresh the LR rows. Not signing anything off yet — this is a re-baseline.
PlasticDigits commented 2026-06-28 22:42:58 +00:00 (Migrated from gitlab.com)

mentioned in merge request !951

mentioned in merge request !951
Brouie commented 2026-06-28 22:58:22 +00:00 (Migrated from gitlab.com)

Redeploy + backend re-verify on 8c56f4b8 done (browser layer still pending). Chain reset to fresh genesis, stamp now 8c56f4b8, deploy schema-verified, indexer rebuilt + caught up.

Heads up on addresses — this redeploy is NOT address-stable like past ones: the new #377 hook contracts shifted the instantiate sequence, so the pair moved (terra146ypn… -> terra16jd56…). Factory/router/fee-discount/treasury/wrap held. The deploy regenerated frontend .env.local with the new addrs, so the laptop just needs a pull + npm ci to pick them up.

Live backend checks on the fresh deploy:

  • #379 indexer hardening, confirmed live: route/solve POST >128KiB -> 413; max_maker_fills clamps (u32::MAX / 0 / 100 all 200, no panic, cap 100); LCD WARN logs redacted to coarse path (no full URL/body); dual-zero rate-limit DoS warn fires.
  • #377 settlement: new pair bytecode deployed (schema match), and a real swap emits the new net_return_amount / hook_fee_amount attrs (hook_fee 0 with no hooks registered, net == return — zero-fee invariant holds). Hook-fee-active path is covered by the contract suite (452/0).
  • #369: route/solve returns 200 + estimate under DB-hybrid, fidelity_check passed, no 502 on the thin-liquidity exploration — old poison symptom gone.
  • REG-00-08: verify-285 / verify-293 / verify-324 all green.
  • Source gates: contracts 452/0; indexer lib 152 + integration 523 (run serial); frontend tsc fixed via !951 + vite bundle builds; vitest 1082/1084 (the 2 are the known terraExplorer localhost-vs-127.0.0.1 env artifact).

Config note for whoever runs the stack: the deploy rewrites indexer/.env back to LCD-heavy=10 / no DB-hybrid on each redeploy, so I relaunch the indexer with ROUTE_SOLVER_DB_HYBRID=1 + RATE_LIMIT_LCD_HEAVY_RPS=0 exported inline (DB-hybrid confirmed live: db_queries>0, lcd_queries 0).

Still laptop-side (not done here):

  • Full UI matrix re-run on the new retail-UX frontend — it's a big redesign, so the prior browser PASS rows are stale.
  • #353 live 2-hop broadcast at the new 1.91M floor (constant fix is in: constants.ts 950k/hop, unit-asserted). Side note: the swarm copy packages/localnet-trading-swarm/src/gas.ts:29 still hardcodes 900k/hop with a "keep in sync with #353" comment, so that one didn't get the bump.
  • #359 hung-RPC double-exec recovery (fix landed under #368/!877) — dapp layer.
  • Clean-host Playwright e2e for LR-00-02/06/07/09/11/14.

Not signing off — LR-00 stays gated on the laptop browser pass + the clean-host e2e. This is the backend re-baseline.

Redeploy + backend re-verify on 8c56f4b8 done (browser layer still pending). Chain reset to fresh genesis, stamp now 8c56f4b8, deploy schema-verified, indexer rebuilt + caught up. Heads up on addresses — this redeploy is NOT address-stable like past ones: the new #377 hook contracts shifted the instantiate sequence, so the pair moved (terra146ypn… -> terra16jd56…). Factory/router/fee-discount/treasury/wrap held. The deploy regenerated frontend .env.local with the new addrs, so the laptop just needs a pull + npm ci to pick them up. Live backend checks on the fresh deploy: - #379 indexer hardening, confirmed live: route/solve POST >128KiB -> 413; max_maker_fills clamps (u32::MAX / 0 / 100 all 200, no panic, cap 100); LCD WARN logs redacted to coarse path (no full URL/body); dual-zero rate-limit DoS warn fires. - #377 settlement: new pair bytecode deployed (schema match), and a real swap emits the new net_return_amount / hook_fee_amount attrs (hook_fee 0 with no hooks registered, net == return — zero-fee invariant holds). Hook-fee-active path is covered by the contract suite (452/0). - #369: route/solve returns 200 + estimate under DB-hybrid, fidelity_check passed, no 502 on the thin-liquidity exploration — old poison symptom gone. - REG-00-08: verify-285 / verify-293 / verify-324 all green. - Source gates: contracts 452/0; indexer lib 152 + integration 523 (run serial); frontend tsc fixed via !951 + vite bundle builds; vitest 1082/1084 (the 2 are the known terraExplorer localhost-vs-127.0.0.1 env artifact). Config note for whoever runs the stack: the deploy rewrites indexer/.env back to LCD-heavy=10 / no DB-hybrid on each redeploy, so I relaunch the indexer with ROUTE_SOLVER_DB_HYBRID=1 + RATE_LIMIT_LCD_HEAVY_RPS=0 exported inline (DB-hybrid confirmed live: db_queries>0, lcd_queries 0). Still laptop-side (not done here): - Full UI matrix re-run on the new retail-UX frontend — it's a big redesign, so the prior browser PASS rows are stale. - #353 live 2-hop broadcast at the new 1.91M floor (constant fix is in: constants.ts 950k/hop, unit-asserted). Side note: the swarm copy packages/localnet-trading-swarm/src/gas.ts:29 still hardcodes 900k/hop with a "keep in sync with #353" comment, so that one didn't get the bump. - #359 hung-RPC double-exec recovery (fix landed under #368/!877) — dapp layer. - Clean-host Playwright e2e for LR-00-02/06/07/09/11/14. Not signing off — LR-00 stays gated on the laptop browser pass + the clean-host e2e. This is the backend re-baseline.
Brouie commented 2026-06-28 23:24:13 +00:00 (Migrated from gitlab.com)

mentioned in merge request !952

mentioned in merge request !952
Brouie commented 2026-06-28 23:24:43 +00:00 (Migrated from gitlab.com)

Knocked out the no-frontend items while the browser pass waits.

Security hardening wave re-verified on the fresh 8c56f4b8 deploy (the #376 -> #381 SEC work): the docs-gates (#391 go/no-go, #407 IBC-hooks, #410 deploy-trace, #416 design-tokens + the check_*_docs validators) and the live LocalTerra smokes (#383 18-dec proxy, #384 fee-discount gas, #396 wrap-mapper pause, #397 gov emergency rehearsal, #399 emergency pause/blacklist cookbook, #400 blacklist decision) all pass — 20 checks green, and the chain is clean afterward (pair not left paused, no lingering blacklist). Launch hardening holds live on the current deploy.

Also shipped the #353 swarm gas drift I flagged above -> MR !952 (swarm gas.ts was still 900k/hop vs the 950k constants.ts fix; could under-budget a 2-hop swarm swap and OOG).

Still browser/laptop-only for LR-00: the full UI matrix re-run on the new retail-UX frontend, #353 2-hop broadcast at the 1.91M floor, #359 hung-RPC recovery, and the clean-host Playwright e2e.

Knocked out the no-frontend items while the browser pass waits. Security hardening wave re-verified on the fresh 8c56f4b8 deploy (the #376 -> #381 SEC work): the docs-gates (#391 go/no-go, #407 IBC-hooks, #410 deploy-trace, #416 design-tokens + the check_*_docs validators) and the live LocalTerra smokes (#383 18-dec proxy, #384 fee-discount gas, #396 wrap-mapper pause, #397 gov emergency rehearsal, #399 emergency pause/blacklist cookbook, #400 blacklist decision) all pass — 20 checks green, and the chain is clean afterward (pair not left paused, no lingering blacklist). Launch hardening holds live on the current deploy. Also shipped the #353 swarm gas drift I flagged above -> MR !952 (swarm gas.ts was still 900k/hop vs the 950k constants.ts fix; could under-budget a 2-hop swarm swap and OOG). Still browser/laptop-only for LR-00: the full UI matrix re-run on the new retail-UX frontend, #353 2-hop broadcast at the 1.91M floor, #359 hung-RPC recovery, and the clean-host Playwright e2e.
Brouie commented 2026-06-29 05:17:53 +00:00 (Migrated from gitlab.com)

Backend/source half of the checklist re-verified on the current deploy (8c56f4b8) — read-only pass, no chain state touched. Progress checkpoint, not the LR-00 sign-off (that stays the browser layer).

Fresh PASS this pass (read-only against the live stack + live swarm traffic):

  • IDX-00-01 health + swagger: /health 200, /swagger-ui/ + /api-docs/openapi.json 200 (40 paths). Swagger is public/unauth — expected, recorded per the #424 M-05 note.
  • IDX-00-02 route/solve GET: EMBER→CORAL 200, estimated_amount_out=15765212187, solver_version=global_v4, paths_considered=5; bad token_in → 400 sanitized, no LCD URL / no SQL leak (#239 clean).
  • IDX-00-03 route/solve POST validation: hybrid_by_hop length ≠ hop count → 400 "length 3 does not match hop count 1", no 500 panic.
  • IDX-00-04 security caps: interval=1m';DROP TABLE-- → 400 allowlist reject; limit=-1 → clamps to exactly 1 candle (#243).
  • IDX-00-06 CG/CMC shapes: /cg/orderbook single object (epoch ms); /cmc/orderbook array-of-one (#223); timestamps numeric (#222).
  • IDX-00-05 sync after swap: newest swarm trade tx 3CB4BF…A784C9 present in pair trades + on-chain (height 108180, code 0) + reflected in its 1m candle; indexer ~1-2s behind chain head, well inside the 30s bound.
  • IDX-00-07 hybrid volume L10: additive invariant holds on a book-only fill (return 991000 = pool 0 + book 991000, #216). PARTIAL — current traffic has no dual-leg split fill (pool>0 AND book>0) to exercise the true double-count guard; the contract suite + prior-baseline pass already cover the split math, so this needs a seeded split-fill to fully re-close live.
  • ONC-00-01 smoke pool swap: read-only LCD pool + pool-only hybrid_simulation, exit 0, return 946 = pool 946 + book 0.
  • ONC-00-03 trusted router: fee-discount is_trusted_router{addr: prod router} → true; router matches VITE_ROUTER_ADDRESS + indexer ROUTER_ADDRESS.
  • INT-00-02 reserves: indexer pair_reserves at block 109026 (100226091620 / 95984780188) exactly match LCD pool{} at the same height, zero drift.
  • SEC-00-03 CORS: Origin: https://evil.example → 200 with NO Access-Control-Allow-Origin echo; allowlist is localhost-only.
  • REG-00-10 lint: lint-contracts clippy/fmt clean (16.77s); lint-frontend 0 errors (5 pre-existing exhaustive-deps warnings) on Node 24.18.
  • REG-00-09 fee-tier doc drift: 11 tiers aligned across docs/reference/fee-discount-tiers.md, tier_fixtures.rs, deploy-dex-local.sh, exit 0.
  • INT-00-04 cosmes patch: cosmesPatch127.test.ts 3/3, #127 fee-override signing patch intact.
  • CFG-00-03 (guard half): the #118/#378 prod-build guard fires and blocks the build with VITE_DEV_MNEMONIC set, exact #118 message, non-zero exit.

On top of the earlier-this-session re-baseline on the same deploy: REG-00-01 contracts 452, REG-00-03 indexer lib 152, REG-00-04 integration 523, REG-00-02 vitest 1082, REG-00-08 verify-285/293/324, the #381 security wave (20 checks), and #379/#377/#369 live.

Two that don't close clean (neither is a new bug):

  • PERF-00-03 (#117 no prod sourcemaps): can't assert yet — npm run build still dies at tsc -b on main with the two spendableRaw bigint-vs-string TS2322s (SwapAdvancedSettings.tsx:130, SwapPage.tsx:1244), so no fresh dist is emitted. That's the same break MR !951 fixes — it just isn't merged, so main can't build a clean bundle. Once !951 lands I re-confirm 0 .map (the stale dist already shows 0 .map and no mnemonic leak, but that's not the current tree).
  • CFG-00-03 (bundle half): "mnemonic absent from a fresh prod bundle" rides on the same build — re-confirm once !951 merges. Stale dist showed no leak.

Still laptop-only for LR-00: the full UI matrix, wallet flows, the chain-mutating swap/pause/create tx rows, E2E REG-00-06/07, a11y, responsive, cross-browser, and the LR-00 sign-off gate — plus the PERF-00-03 / CFG-00-03 bundle re-run once the build is green.

@PlasticDigits — merging !951 unblocks the frontend build gate (PERF-00-03 + the bundle half of CFG-00-03); everything else here is green or laptop-gated.

Backend/source half of the checklist re-verified on the current deploy (8c56f4b8) — read-only pass, no chain state touched. Progress checkpoint, not the LR-00 sign-off (that stays the browser layer). Fresh PASS this pass (read-only against the live stack + live swarm traffic): - IDX-00-01 health + swagger: `/health` 200, `/swagger-ui/` + `/api-docs/openapi.json` 200 (40 paths). Swagger is public/unauth — expected, recorded per the #424 M-05 note. - IDX-00-02 route/solve GET: EMBER→CORAL 200, `estimated_amount_out=15765212187`, `solver_version=global_v4`, `paths_considered=5`; bad `token_in` → 400 sanitized, no LCD URL / no SQL leak (#239 clean). - IDX-00-03 route/solve POST validation: `hybrid_by_hop` length ≠ hop count → 400 "length 3 does not match hop count 1", no 500 panic. - IDX-00-04 security caps: `interval=1m';DROP TABLE--` → 400 allowlist reject; `limit=-1` → clamps to exactly 1 candle (#243). - IDX-00-06 CG/CMC shapes: `/cg/orderbook` single object (epoch ms); `/cmc/orderbook` array-of-one (#223); timestamps numeric (#222). - IDX-00-05 sync after swap: newest swarm trade tx `3CB4BF…A784C9` present in pair trades + on-chain (height 108180, code 0) + reflected in its 1m candle; indexer ~1-2s behind chain head, well inside the 30s bound. - IDX-00-07 hybrid volume L10: additive invariant holds on a book-only fill (return 991000 = pool 0 + book 991000, #216). **PARTIAL** — current traffic has no dual-leg split fill (pool>0 AND book>0) to exercise the true double-count guard; the contract suite + prior-baseline pass already cover the split math, so this needs a seeded split-fill to fully re-close live. - ONC-00-01 smoke pool swap: read-only LCD `pool` + pool-only `hybrid_simulation`, exit 0, return 946 = pool 946 + book 0. - ONC-00-03 trusted router: fee-discount `is_trusted_router{addr: prod router}` → true; router matches `VITE_ROUTER_ADDRESS` + indexer `ROUTER_ADDRESS`. - INT-00-02 reserves: indexer `pair_reserves` at block 109026 (100226091620 / 95984780188) exactly match LCD `pool{}` at the same height, zero drift. - SEC-00-03 CORS: `Origin: https://evil.example` → 200 with NO `Access-Control-Allow-Origin` echo; allowlist is localhost-only. - REG-00-10 lint: `lint-contracts` clippy/fmt clean (16.77s); `lint-frontend` 0 errors (5 pre-existing `exhaustive-deps` warnings) on Node 24.18. - REG-00-09 fee-tier doc drift: 11 tiers aligned across `docs/reference/fee-discount-tiers.md`, `tier_fixtures.rs`, `deploy-dex-local.sh`, exit 0. - INT-00-04 cosmes patch: `cosmesPatch127.test.ts` 3/3, #127 fee-override signing patch intact. - CFG-00-03 (guard half): the #118/#378 prod-build guard fires and blocks the build with `VITE_DEV_MNEMONIC` set, exact #118 message, non-zero exit. On top of the earlier-this-session re-baseline on the same deploy: REG-00-01 contracts 452, REG-00-03 indexer lib 152, REG-00-04 integration 523, REG-00-02 vitest 1082, REG-00-08 verify-285/293/324, the #381 security wave (20 checks), and #379/#377/#369 live. Two that don't close clean (neither is a new bug): - **PERF-00-03 (#117 no prod sourcemaps):** can't assert yet — `npm run build` still dies at `tsc -b` on main with the two `spendableRaw` bigint-vs-string TS2322s (`SwapAdvancedSettings.tsx:130`, `SwapPage.tsx:1244`), so no fresh dist is emitted. That's the **same break MR !951 fixes** — it just isn't merged, so main can't build a clean bundle. Once !951 lands I re-confirm 0 `.map` (the stale dist already shows 0 `.map` and no mnemonic leak, but that's not the current tree). - **CFG-00-03 (bundle half):** "mnemonic absent from a fresh prod bundle" rides on the same build — re-confirm once !951 merges. Stale dist showed no leak. Still laptop-only for LR-00: the full UI matrix, wallet flows, the chain-mutating swap/pause/create tx rows, E2E REG-00-06/07, a11y, responsive, cross-browser, and the LR-00 sign-off gate — plus the PERF-00-03 / CFG-00-03 bundle re-run once the build is green. @PlasticDigits — merging !951 unblocks the frontend build gate (PERF-00-03 + the bundle half of CFG-00-03); everything else here is green or laptop-gated.
Brouie commented 2026-06-29 05:22:11 +00:00 (Migrated from gitlab.com)

Correcting myself on the two build-gated rows above — I was on a stale local checkout; the build is actually green.

!951 is merged. origin/main is at 767dcd1e, 4 commits ahead of the 8c56f4b8 deploy, and the whole range is frontend-only (zero diff to smartcontracts/ or indexer/), so the chain deploy stays current — no redeploy. My local tree was still pinned at the deployed 8c56f4b8, which is why the batch re-hit the old spendableRaw tsc break that !951 already fixed.

Built origin/main's frontend to confirm (production build, not a dev server):

  • PERF-00-03 (#117): PASS — npm run build green (tsc -b clean, vite built in ~15s), dist/ ships 0 *.map files.
  • CFG-00-03 (bundle half): PASS — the test1 mnemonic (notice oak worry limit …) is not in the bundle. The only VITE_DEV_MNEMONIC hit in dist is the guard's own error string ("VITE_DEV_MNEMONIC is required for the dev wallet…") — the env-var name, not its value.

So both flip to PASS; there's no open frontend-build issue (the build half of the checklist is green on current origin/main). The one genuine PARTIAL stands: IDX-00-07 needs a dual-leg split-fill (pool>0 AND book>0) to re-close the no-double-count guard live — current swarm traffic is pool-only AMM + book-only fills.

Correcting myself on the two build-gated rows above — I was on a stale local checkout; the build is actually green. !951 is **merged**. origin/main is at `767dcd1e`, 4 commits ahead of the `8c56f4b8` deploy, and the whole range is **frontend-only** (zero diff to `smartcontracts/` or `indexer/`), so the chain deploy stays current — no redeploy. My local tree was still pinned at the deployed `8c56f4b8`, which is why the batch re-hit the old `spendableRaw` tsc break that !951 already fixed. Built origin/main's frontend to confirm (production build, not a dev server): - **PERF-00-03 (#117): PASS** — `npm run build` green (tsc -b clean, vite built in ~15s), `dist/` ships **0** `*.map` files. - **CFG-00-03 (bundle half): PASS** — the test1 mnemonic (`notice oak worry limit …`) is **not** in the bundle. The only `VITE_DEV_MNEMONIC` hit in `dist` is the guard's own error string (`"VITE_DEV_MNEMONIC is required for the dev wallet…"`) — the env-var name, not its value. So both flip to PASS; there's no open frontend-build issue (the build half of the checklist is green on current origin/main). The one genuine PARTIAL stands: **IDX-00-07** needs a dual-leg split-fill (pool>0 AND book>0) to re-close the no-double-count guard live — current swarm traffic is pool-only AMM + book-only fills.
Brouie commented 2026-06-29 07:52:30 +00:00 (Migrated from gitlab.com)

mentioned in merge request !953

mentioned in merge request !953
Brouie commented 2026-06-29 07:53:00 +00:00 (Migrated from gitlab.com)

mentioned in issue #421

mentioned in issue #421
Brouie commented 2026-06-29 14:55:22 +00:00 (Migrated from gitlab.com)

Knocked out the VPS-doable rows still open on the current deploy (8c56f4b8) while the stack was up and the swarm idle. On-chain actions cross-checked end to end from the contract event + the indexer API + Postgres. Progress checkpoint — LR-00 sign-off still rides the laptop browser pass.

IDX-00-07 hybrid volume L10 — now fully closed live (this was the one open PARTIAL). Recent traffic only ever had pool-only AMM + book-only fills, so I seeded a genuine dual-leg split: placed a controlled ask (order 29, 20 EMBER @0.9, rests at 19.82M after the 90bps maker fee), then bought EMBER with 36 CORAL split pool_input 18M / book_input 18M (max_maker_fills 1, book_start_hint 29 to confine the book leg to my own order). Swap tx 6C0685B2, code 0:

  • on-chain wasm: pool_return_amount 19,713,930 AND book_return_amount 19,641,620 (both legs > 0 = real split); return_amount 39,355,550 = pool + book exactly; net_return_amount 39,355,550 / hook_fee_amount 0 (no hooks registered, net == return — the #377 zero-fee invariant); limit_book_offer_consumed 17,838,000.
  • indexer trade row (id 9979): return_amount == pool_leg_volume + book_leg_volume (19,713,930 + 19,641,620), both > 0.
  • no double-count: /stats volume_quote rose by exactly the one return (53,454,244,095 -> 53,493,599,645); /cg/tickers cl8y_extensions pool_leg + book_leg == target_volume (53,472,967,025 + 20,632,620 = 53,493,599,645), hybrid_trade_count 1 -> 2. The headline is SUM(return_amount) over swap_events alone — the maker-fill ledger is never summed in, which is the #216 guard. Order 29 fully consumed, book back to its prior head.

ONC-00-02 factory pause semantics — re-confirmed on the new #377 pair bytecode. Heads up: pause is governance-only and governance was rotated off test1 onto the 2-of-3 gov multisig (terra1ltjjf30..., the #397/SEC-B09 rotation), so it runs through the factory SetPairPaused signed 2-of-3, not a single key.

  • pause tx F4094031 (multisig) -> is_paused true.
  • swap while paused: tx 633ECC50 code 5, raw_log "Contract is paused" (the assert_not_paused gate at the Receive dispatcher, before the hook is even parsed).
  • limit-place while paused: same gate, "Contract is paused".
  • unpause tx 316BAB58 -> is_paused false; re-ran the swap, tx ECECB8E0 code 0, action=swap with the #377 net_return_amount attr -> pair live again. Left unpaused + clean.

ONC-00-04 hybrid sim vs exec (L8) — got this off the split-fill: the LCD hybrid_simulation predicted return 39,355,550 / pool 19,713,930 / book 19,641,620, and the on-chain execution matched to the micro-unit. 0% drift, well inside the L8 tolerance.

CON-00-01 swarm stress (backend half) — the 4h / 33-worker soak gave this its data: the indexer carried the load and is still healthy after ~15.7h continuous at a flat 25MB RSS, no OOM, no crash. Zero ERROR-level log lines over the window; the WARN volume is the offline-env oracle (no USD price source locally) plus benign rate-limit warns. UI-responsiveness half stays laptop.

INT-00-03 reorg replay (#287) — rewound the indexer cursor past my test swaps and let it re-poll ~5,900 blocks to head. swap_events stayed at 9,980 rows, distinct == total, my split-fill row still single, zero (tx_hash, pair_id, swap_index) dup groups. ON CONFLICT DO NOTHING holds on the current build. One good thing on the way: the #362 reorg-halt guard does its job — a checkpoint whose stored block-hash doesn't match canonical makes the indexer halt for operator recovery instead of blindly re-indexing; the documented empty-hash recovery path resumes it clean. Indexer back caught up to head, bound==pidfile, DB-hybrid live.

Moves to PASS on 8c56f4b8: IDX-00-07, ONC-00-02, ONC-00-04, CON-00-01 (backend), INT-00-03. VPS-side queue is exhausted again — what's left for sign-off is the laptop browser matrix + the clean-host Playwright e2e (REG-00-06/07, XBR-00-03, CON-00-02, a11y), unchanged.

Knocked out the VPS-doable rows still open on the current deploy (8c56f4b8) while the stack was up and the swarm idle. On-chain actions cross-checked end to end from the contract event + the indexer API + Postgres. Progress checkpoint — LR-00 sign-off still rides the laptop browser pass. IDX-00-07 hybrid volume L10 — now fully closed live (this was the one open PARTIAL). Recent traffic only ever had pool-only AMM + book-only fills, so I seeded a genuine dual-leg split: placed a controlled ask (order 29, 20 EMBER @0.9, rests at 19.82M after the 90bps maker fee), then bought EMBER with 36 CORAL split pool_input 18M / book_input 18M (max_maker_fills 1, book_start_hint 29 to confine the book leg to my own order). Swap tx 6C0685B2, code 0: - on-chain wasm: pool_return_amount 19,713,930 AND book_return_amount 19,641,620 (both legs > 0 = real split); return_amount 39,355,550 = pool + book exactly; net_return_amount 39,355,550 / hook_fee_amount 0 (no hooks registered, net == return — the #377 zero-fee invariant); limit_book_offer_consumed 17,838,000. - indexer trade row (id 9979): return_amount == pool_leg_volume + book_leg_volume (19,713,930 + 19,641,620), both > 0. - no double-count: /stats volume_quote rose by exactly the one return (53,454,244,095 -> 53,493,599,645); /cg/tickers cl8y_extensions pool_leg + book_leg == target_volume (53,472,967,025 + 20,632,620 = 53,493,599,645), hybrid_trade_count 1 -> 2. The headline is SUM(return_amount) over swap_events alone — the maker-fill ledger is never summed in, which is the #216 guard. Order 29 fully consumed, book back to its prior head. ONC-00-02 factory pause semantics — re-confirmed on the new #377 pair bytecode. Heads up: pause is governance-only and governance was rotated off test1 onto the 2-of-3 gov multisig (terra1ltjjf30..., the #397/SEC-B09 rotation), so it runs through the factory SetPairPaused signed 2-of-3, not a single key. - pause tx F4094031 (multisig) -> is_paused true. - swap while paused: tx 633ECC50 code 5, raw_log "Contract is paused" (the assert_not_paused gate at the Receive dispatcher, before the hook is even parsed). - limit-place while paused: same gate, "Contract is paused". - unpause tx 316BAB58 -> is_paused false; re-ran the swap, tx ECECB8E0 code 0, action=swap with the #377 net_return_amount attr -> pair live again. Left unpaused + clean. ONC-00-04 hybrid sim vs exec (L8) — got this off the split-fill: the LCD hybrid_simulation predicted return 39,355,550 / pool 19,713,930 / book 19,641,620, and the on-chain execution matched to the micro-unit. 0% drift, well inside the L8 tolerance. CON-00-01 swarm stress (backend half) — the 4h / 33-worker soak gave this its data: the indexer carried the load and is still healthy after ~15.7h continuous at a flat 25MB RSS, no OOM, no crash. Zero ERROR-level log lines over the window; the WARN volume is the offline-env oracle (no USD price source locally) plus benign rate-limit warns. UI-responsiveness half stays laptop. INT-00-03 reorg replay (#287) — rewound the indexer cursor past my test swaps and let it re-poll ~5,900 blocks to head. swap_events stayed at 9,980 rows, distinct == total, my split-fill row still single, zero (tx_hash, pair_id, swap_index) dup groups. ON CONFLICT DO NOTHING holds on the current build. One good thing on the way: the #362 reorg-halt guard does its job — a checkpoint whose stored block-hash doesn't match canonical makes the indexer halt for operator recovery instead of blindly re-indexing; the documented empty-hash recovery path resumes it clean. Indexer back caught up to head, bound==pidfile, DB-hybrid live. Moves to PASS on 8c56f4b8: IDX-00-07, ONC-00-02, ONC-00-04, CON-00-01 (backend), INT-00-03. VPS-side queue is exhausted again — what's left for sign-off is the laptop browser matrix + the clean-host Playwright e2e (REG-00-06/07, XBR-00-03, CON-00-02, a11y), unchanged.
Brouie commented 2026-06-29 14:55:29 +00:00 (Migrated from gitlab.com)

mentioned in issue #372

mentioned in issue #372
Brouie commented 2026-06-30 03:15:16 +00:00 (Migrated from gitlab.com)

Backend re-verify done on the new tree — folded the #431/#432/#433 indexer fixes into the verified set.

Advanced local main to origin/main (2a06048b). No chain redeploy: zero smartcontracts/ source diff in the range, deploy stamp stays 8c56f4b8 (factory terra1hrpna9, pair terra16jd56). The indexer is the only backend that moved — #431 (capped-list lower-bound limit tests), #432 (CSV formula-injection neutralize in trader exports), #433/SEC-F13 (startup log-secret guard). Rebuilt the indexer at 2a06048b and relaunched DB-hybrid.

Source gates on 2a06048b:

  • indexer lib 158/0 (was 152; the +6 include the 4 csv_escape_cell neutralization tests)
  • security integration 35/0 (serial)

Live backend (LR-00-06 re-confirmed on the new build):

  • IDX-00-02: route/solve valid -> 200 (3-hop, quote_kind indexer_hybrid_db / solver_version global_v4, est_out 17,051,098,350); malformed token and negative amount both -> 400, not 500
  • IDX-00-03 (#431): leaderboard limit -1/0/999999 -> 200 clamped, limit=abc -> 400; pairs limit honored
  • IDX-00-04: /cg/tickers 25 tickers correct shape, /cmc/summary array
  • IDX-00-06: error bodies sanitized (token_in not found / Pair not found / serde deserialize msg), zero SQL/LCD/secret leakage in bodies; zero password occurrences in the boot log (the #433 guard)
  • #432: trader CSV export serves text/csv attachment, well-formed RFC4180; the =/+/-/@ formula-prefix neutralizer is unit-proven

IDX-00-05 (sync-after-swap) stands — the poller is unchanged in this range and the indexer is syncing live (lag ~1); didn't broadcast a fresh swap this pass.

So the VPS/backend layer is green on the new tree. Still owed for LR-00-15 sign-off: the laptop retail-UX UI matrix + the clean-host Playwright e2e (REG-00-06/07, XBR-00-03, CON-00-02, verify-295, axe) — both off-box, not this layer.

Backend re-verify done on the new tree — folded the #431/#432/#433 indexer fixes into the verified set. Advanced local main to origin/main (2a06048b). No chain redeploy: zero smartcontracts/ source diff in the range, deploy stamp stays 8c56f4b8 (factory terra1hrpna9, pair terra16jd56). The indexer is the only backend that moved — #431 (capped-list lower-bound limit tests), #432 (CSV formula-injection neutralize in trader exports), #433/SEC-F13 (startup log-secret guard). Rebuilt the indexer at 2a06048b and relaunched DB-hybrid. Source gates on 2a06048b: - indexer lib 158/0 (was 152; the +6 include the 4 csv_escape_cell neutralization tests) - security integration 35/0 (serial) Live backend (LR-00-06 re-confirmed on the new build): - IDX-00-02: route/solve valid -> 200 (3-hop, quote_kind indexer_hybrid_db / solver_version global_v4, est_out 17,051,098,350); malformed token and negative amount both -> 400, not 500 - IDX-00-03 (#431): leaderboard limit -1/0/999999 -> 200 clamped, limit=abc -> 400; pairs limit honored - IDX-00-04: /cg/tickers 25 tickers correct shape, /cmc/summary array - IDX-00-06: error bodies sanitized (token_in not found / Pair not found / serde deserialize msg), zero SQL/LCD/secret leakage in bodies; zero password occurrences in the boot log (the #433 guard) - #432: trader CSV export serves text/csv attachment, well-formed RFC4180; the =/+/-/@ formula-prefix neutralizer is unit-proven IDX-00-05 (sync-after-swap) stands — the poller is unchanged in this range and the indexer is syncing live (lag ~1); didn't broadcast a fresh swap this pass. So the VPS/backend layer is green on the new tree. Still owed for LR-00-15 sign-off: the laptop retail-UX UI matrix + the clean-host Playwright e2e (REG-00-06/07, XBR-00-03, CON-00-02, verify-295, axe) — both off-box, not this layer.
Brouie commented 2026-07-01 11:30:46 +00:00 (Migrated from gitlab.com)

Track A backend re-verified on a full redeploy to current main (21381a0e). This range touched contracts and indexer, so it's a real chain + indexer redeploy this pass, not a no-op advance.

Source gates on 21381a0e:

  • contracts 456/0
  • indexer lib 167/0
  • indexer integration 561/0 (serial)

Live backend on the fresh deploy:

  • IDX-00-02: route/solve valid -> 200 (DB-hybrid, quote_kind indexer_pool_db / solver_version global_v4, fidelity passed, est_out 15,753,179,728); malformed token and negative amount both -> 400, not 500
  • IDX-00-03: leaderboard limit -1/0/999999 -> 200 clamped, limit=abc -> 400
  • IDX-00-04: /cg/tickers 25 tickers correct shape, /cmc/summary array
  • IDX-00-05: broadcast a live pair swap (F64C7FBF) and a router swap (957D4762) EMBER->CORAL — both indexed and sitting at the head of the pair trades feed within a couple blocks
  • IDX-00-06: error bodies sanitized ("token_in not found in indexer assets"), zero SQL/LCD/secret leakage

The SEC-I contract + indexer fixes that landed in this range are all live-verified on the new deploy (details on their trackers): #455 factory registry guard (on-chain unregistered -> code 5, registered -> code 0), #456 blacklist default-deny (real pair + router swaps code 0 while the factory answers healthy), #451 empty-FACTORY guard (rejects in every RUN_MODE), #458 dual-zero rate-limit bind guard, #459 ILIKE wildcard escape (q=% -> 0, not match-all). Addresses held stable across the redeploy (factory terra1hrpna9, pair terra16jd56, router terra1yvgh8), so no env churn.

Backend/Track-A layer is green on 21381a0e; the retail-UX UI matrix rows are the remaining piece.

Track A backend re-verified on a full redeploy to current main (21381a0e). This range touched contracts and indexer, so it's a real chain + indexer redeploy this pass, not a no-op advance. Source gates on 21381a0e: - contracts 456/0 - indexer lib 167/0 - indexer integration 561/0 (serial) Live backend on the fresh deploy: - IDX-00-02: route/solve valid -> 200 (DB-hybrid, quote_kind indexer_pool_db / solver_version global_v4, fidelity passed, est_out 15,753,179,728); malformed token and negative amount both -> 400, not 500 - IDX-00-03: leaderboard limit -1/0/999999 -> 200 clamped, limit=abc -> 400 - IDX-00-04: /cg/tickers 25 tickers correct shape, /cmc/summary array - IDX-00-05: broadcast a live pair swap (F64C7FBF) and a router swap (957D4762) EMBER->CORAL — both indexed and sitting at the head of the pair trades feed within a couple blocks - IDX-00-06: error bodies sanitized ("token_in not found in indexer assets"), zero SQL/LCD/secret leakage The SEC-I contract + indexer fixes that landed in this range are all live-verified on the new deploy (details on their trackers): #455 factory registry guard (on-chain unregistered -> code 5, registered -> code 0), #456 blacklist default-deny (real pair + router swaps code 0 while the factory answers healthy), #451 empty-FACTORY guard (rejects in every RUN_MODE), #458 dual-zero rate-limit bind guard, #459 ILIKE wildcard escape (q=% -> 0, not match-all). Addresses held stable across the redeploy (factory terra1hrpna9, pair terra16jd56, router terra1yvgh8), so no env churn. Backend/Track-A layer is green on 21381a0e; the retail-UX UI matrix rows are the remaining piece.
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-07-07 02:10:10 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-dex-terraclassic#337
No description provided.