> For the complete documentation index, see [llms.txt](https://docs.trover.tech/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.trover.tech/engineering/status-2026-09-08.md).

# Status 2026-09-08: built, live, not live, next

One page for the state of Trover after the 2026-09-05 to 2026-09-08 rounds. Per-round evidence and deploy commands are in the `VERIFY-2026-09-0[5-8]-*.md` files; contract procedures in `contracts-runbook.md`; X setup in `x-agent-setup.md`. Frontend deploys from a push to `main` (Vercel); api, worker and nft-realtime deploy by hand on the server, one at a time.

## a. Live on production

### Site (trover.tech, dex.trover.tech)

* Fonts ship: Bricolage Grotesque (display), Hanken Grotesk (body), IBM Plex Mono (mono) through `next/font/google`, self-hosted, defining `--font-display/--font-body/--font-mono`. Before 2026-09-07 those variables were never defined and every `font-mono`/`font-display` fell back to the OS.
* One status vocabulary: `StateChip` (outlined pill, colour on text and border only, state written out, evidence after a middle dot, never animates). No coloured or pulsing dots remain: `DataFreshness`, `NftLifecycleChip`, the trending and DEX home indicators, chart placeholders and `Badge` all use it.
* `Card` (16 px radius, hairline, flat fill, `inset` at 12 px); radii capped at `rounded-2xl`; no glows, hover lifts or hover scales; 11 px text floor (437 sites); kickers removed above headings; English em-dashes out of JSX.
* Trovernomics page rebuilt for the token economy: four-way split (35% holders as stock tokens, 15% league, 20% buyback and burn, 30% treasury) on every source, balance-only holder weighting (hourly snapshots, 100k TROVER minimum, seven-day claims), the buyback keeper, rescue paths, live counters from `GET /v1/token/economics`. The Orbits page and the Planets probe are gone. `token-economics.md` matches the page.
* NFT terminal: newest listings first, sale flash and row flicker, basket with totals with or without a wallet, hover buy pill, Trover actions shown as processing; marketplace with true chain badges, lifecycle chips on every row, live deltas, `minted/max (pct)`, "last mint x ago", per-network leaderboards (`scope=chain`, "all networks" opt-in); extension conflict notice for the Compass Wallet / Revoke.cash stall.

### API and worker

* Chain-first NFT ingestion. Measured 2026-09-07 11:20Z: 1,204 fills per hour through the websocket lanes, median 1.1 s after the block, all accepted. On 2026-09-06 about 85% of live fills were being rejected by a redundant RPC re-verification (1,059 to 1,511 rejected per 30-minute bucket); a receipt the live lane already fetched is now trusted, unverifiable is no longer rejected, and a repair job re-accepts old rows on a 100 s budget every 2 minutes (backlog was 58,862 rows).
* Mints: per-chain lane guards (Robinhood no longer waits on a 30 to 46 minute Ink scan); a window's mints written as one batch: 693 to 1,152 mints per run in 60 to 70 s (was 191 in 170 s), WAL waiters 24 to 4.
* Worker stability: 16 OOM restarts between 2026-09-05 and 09-06 traced to scan pile-up, an unbounded OpenSea response cache (capped at 300 entries) and the DEX swap tape holding hours of blocks (now per-window writes, 6,000 blocks per tick). `worker memory` log line every 60 s.
* RPC spend: free endpoints first, paid ones an unranked fallback; Alchemy entry capped at `cu=15M` after 24.4M of 26.7M CU went in two days; both websocket lanes share per-fill receipt work.
* Discovery lists warmed into Redis every 60 s (trending, top, new per chain); the page is served stale-while-revalidate (hit 12 ms, cold miss was 6.0 s); responses carry `freshness` (head block, indexed block, lag, age); sold-out badge for 15 minutes after the last mint; per-network leaderboards topped up from our own rows.
* Rate limiting: `trustProxy` on, 600/min per visitor keyed on `cf-connecting-ip`; 4,994 of 4,995 429s in a day had been our own shared bucket. OpenSea paced at 250 ms with a reserve for the API.
* Agents on the NFT index: 12 new capabilities (`nft_collection_detail`, `nft_price_history`, `nft_activity`, `nft_orderbook`, `nft_traits`, `nft_holders`, `nft_drops`, `nft_trending`, `nft_discovery`, `nft_snipe_status`, `nft_snipe_manage`, `nft_trover`) reading the API's own routes; X gets the 200-character summary, web gets summary plus data; MCP answers the same reads in-process. Details in `agent-orchestration.md` and `customer-mcp.md`. `contract-balance-watch` runs every 10 minutes and is a no-op until stack addresses exist.
* Reveal sniping (`NFT_SNIPE_ENABLED` defaults to true) with the migration from 2026-09-05 applied.

### Contracts on mainnet (4663)

Nothing new. Live: `TroverStockDistributor` `0x53f6B2498374ebEB8c47B0C4a83b0eF78ea071CC` and the 2-of-2 Safe `0x0e491ff9dB0956558891a71587015a8Cc64FaF35`. The stock distributor's source still names `@troverobinhood` in its immutable X constants.

## b. Built and rehearsed, not on mainnet

The NFT collection was dropped on 2026-09-08. The stack is now six contracts: `TroverBuybackBurn` (new), `TroverEthDistributor`, `TroverLeagueVault`, `TroverRevenueRouter` (four-way `Split` per source, `setSplit`), `TroverXClaimEscrow` (`forceRelease`), `TroverAtomicFeeExecutor`. Every ETH-holding contract has pause and rescue paths; the Hardhat suite is 17 passing (`TroverRescuePaths`, `TroverTokenEconomics`, `TroverEthDistributor`). `deploy-stack.mjs` accepts a single-signer admin with `TROVER_STACK_ALLOW_EOA_ADMIN=true`; `safe-rescue.mjs` executes directly for an EOA admin. The admin page (`/internal`) deploys the same stack from a connected wallet (`ContractStackDeployer`, resumable, env lines and manifest shown; artifacts in `apps/web/src/lib/contracts/stack-artifacts.json`).

Deployed on Robinhood testnet 46630 on 2026-09-08 (EOA admin `0xD214…F63e`), manifest `packages/contracts/deployments/robinhood-46630-stack.json`:

| Contract                | Address                                      |
| ----------------------- | -------------------------------------------- |
| TroverBuybackBurn       | `0xaF740795dB64Cf13260A7AC8514493d304436133` |
| TroverEthDistributor    | `0x68cF9b6a711c8Ce7Adf8E1e066CcBCaBDE542A71` |
| TroverLeagueVault       | `0xE3a39500e5251B713Ff29D2838A31782B25d7fcD` |
| TroverRevenueRouter     | `0xd93D0F7fD5376A8fecF3dB856815B8Eb53f25DD9` |
| TroverXClaimEscrow      | `0xb94B086cfa56e5E5e7BF1fc5e561bA054b453711` |
| TroverAtomicFeeExecutor | `0x3ecbb30B2aE76EdbE666564EFe2565188505C1AB` |

All nine post-deploy assertions passed. The 39-step rehearsal (`robinhood-46630-rehearsal.json`, under 0.003 test ETH): a bot-fee route landing 35/15/20/30, `setToken` once (second refused), `buyAndBurn` refused through a non-allowlisted router and executed through the mock (0.2 tokens to the dead address), deferred router payout reassigned and withdrawn, `setSplit` changed and restored, sweeps on router, league and executor, `recoverUnreserved`, escrow `forceRelease` after six 60-second delays, and pause/unpause on all six.

Backend for the token economy (built, typechecked, deploying): worker job `buyback-burn` every 10 minutes (no-op until `BUYBACK_ENABLED` and the sink's token are set), `GET /v1/token/economics`, agent capability `token_economics` replacing `nft_trover` on web chat, X and MCP.

The mainnet run needs (admin page or script):

* admin `0x1cb528AcfB28AE917ee7473225c01f5F8F23D631` (single signer);
* treasury, league manager, voucher signer address, platform fee wallet, router allowlist, keeper (the claim-automation account's address);
* `TROVER_TOKEN_ADDRESS` empty; `burn.setToken` after the launch, then `BUYBACK_ENABLED=true` on the server;
* a connected wallet with ETH for gas (whole stack was under 0.003 ETH on testnet at 0.01 gwei; mainnet gas is capped at 6M per transaction).

After the run: commit the manifest and `deployments/abi/`, paste the env lines into the server `.env` (backup first), redeploy api and worker, confirm `contract-balance-watch` logs one line per contract.

## c. Waiting on the user

* Server `.env` for X, per `x-agent-setup.md`: OAuth 1.0a and OAuth 2.0 user tokens generated as `@troveragent`, `BOT_X_USER_ID`, `BOT_X_USERNAME`, `PROJECT_X_USERNAME`, `FOUNDER_X_USERNAME` (unset on the server), webhook re-registration and the subscribe call, then a redeploy of api and worker. Until then X replies fail at call time, not at boot.
* The `@troveragent` handle is baked into `TroverEthDistributor` (`PROJECT_X_URL`/`AGENT_X_URL` constants); change them before the mainnet run if the handle changes.
* Agent env on the server: `AGENT_INTERNAL_API_URL`, `AGENT_ORCHESTRATOR_KEY` (same value in api and worker), `AGENT_RUN_TIMEOUT_SECONDS`; confirm they are set, and that the stack keys (`LEAGUE_VAULT_ADDRESS`, `BUYBACK_BURN_ADDRESS`, `OPENSEA_REVENUE_ROUTER_ADDRESS`, …) stay empty until mainnet.
* Postgres settings that need a restart (the reload-safe ones, `wal_compression=on`, `max_wal_size=4GB`, `checkpoint_timeout=15min`, are applied): `shared_buffers=4GB`, `wal_buffers=64MB`, `effective_cache_size=24GB`. Our Postgres ran on defaults (128 MB `shared_buffers` for a 38 GB database).
* The other application on the box: `teztap-db-1` shares the one disk (8.8 TB written against our 3.9 TB; 41% I/O wait measured). Its load is the ceiling on our write throughput and on statement timeouts.
* Contract compile and suite were run on 2026-09-08 for the testnet rehearsal: 17 passing. Still yours to run: `slither` and `pnpm vitest run tests/agent-planner.test.ts tests/agent-nft-reads.test.ts`.

## d. Known issues

* Statement timeouts under load: api 15 s, worker 120 s (`docker-compose.production.yml`). They kill the query instead of the service, which is the intent, but under I/O wait heavy aggregations on the 5 GB `nft_market_events` tape can still hit them; that table should be time-partitioned. Three unbounded in-process caches noted on 2026-09-04 (`portfolio-routes`, `stabledex-holders`, `stabledex-routes`) are unchanged.
* The other app's database competes for the same disk (above).
* Mint gap drain in progress: the 257,038-block Robinhood mint gap (56,542,148 to 56,799,186) is being drained from the Redis marker `trover:nft-mint-gap:v1:robinhood`; about 2.5 h at the measured 2,000 blocks per 70 s. The lane logs "gap drained" and deletes the key when done.
* Alchemy websocket subscription charges are not visible to our RPC meter; if the dashboard still shows spend, swap the Alchemy `wss` out of `ROBINHOOD_NFT_WS_URLS`.
* Design residue: `" — "` remains in code comments and in ru/az copy; `.eyebrow` stays on table column headers.
* Contracts compiled and tested only by the user (no-build rule); Solidity written on 2026-09-07 has passed `node --check` and `tsc` but Hardhat and slither runs are the user's.

## e. Plan

1. User: run slither and the two vitest files; report failures by case name.
2. User: fill the server `.env` for X (`@troveragent`), redeploy api and worker, run the three checks in `x-agent-setup.md`.
3. Claude: fix anything the X checks or the tests surface.
4. User: restart Postgres with the three memory settings during a quiet window; Claude: confirm WAL waiters and I/O wait afterwards.
5. Claude: confirm the mint gap marker is gone and the newest mint is within a minute of `now()`; then remove `NFT_ONCHAIN_MAX_LAG_BLOCKS=1500000` if it is still raised.
6. User: on `/internal`, connect a wallet with gas, check the inputs, deploy the stack on mainnet (`DEPLOY 4663`); Claude: review the manifest and assertions, commit them, write the env lines; user pastes them and redeploys api and worker.
7. Claude: a first rescue drill on mainnet through `safe-rescue.mjs` (pause and unpause the router) from the admin key.
8. After the Pons launch: `burn.setToken`, `BUYBACK_ENABLED=true`, watch the first `buyback-burn` runs and the first holder tranche.
9. Later: `nft_market_events` partitioning; the read-only MCP server for the OpenAI directory.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.trover.tech/engineering/status-2026-09-08.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
