---
name: stable-launch-ops
description: "Use for Stable Launch chain 988 deploy or testnet asks."
version: 1.0.0
---

> Oracle native tools: `oracle_cli` (read/prepare), `vault_status`, `signer_status`, `signer_execute` (needs human confirmationNonce), `skill_load`. No generic shell. No fleet SSH.


# Stable Launch ops (chain 988)

Repos: `~/projects/stable-launch` (contracts) · `stable-launch-web` · `stable-launch-indexer` · `stable-agent` (personal signals, never bundled into public web).

Board: Obsidian `Projects/Stable Launch Board.md` · preview `https://stablelaunch.demi.la`

## Chain fact (do not invent a testnet)

- Product chain is **Stable Mainnet chainId 988** only in this stack.
- Addresses file: `stable-launch/addresses/988.json` (null until factory GO).
- Public RPC: `https://rpc.stable.xyz` (pruned ~156k blocks — indexer needs **archive** paid RPC for first backfill).
- There is **no** separate Stable public testnet config in-repo. INTERFACE.md "testnet first" means **anvil-988 fork rehearsal**, not a second public network.

When DEMI asks **"should we deploy on testnet to test?"**:

| Path | Do it? | Why |
|---|---|---|
| Traffic stack (paid RPC + indexer host + CF secrets/DNS) | **Yes** | Proves launch-day read path; no factory GO |
| Frontend edge cutover off demi-poly | **Yes** | demi-poly is forbidden for launch frontend/indexer |
| Physical wallet QA on 988 | **Yes** | Cannot verify headlessly |
| Persistent **anvil fork of 988** + point web/indexer at it | **Yes** | Full E2E, zero mainnet spend |
| Factory `forge script --broadcast` on live 988 | **No** without explicit GO | Real USDT0 gas + irreversible keeper wiring |
| Invented external "Stable testnet" deploy | **No** | Not in config; fork already covers contract risk |

## Already proven (do not re-litigate)

- Foundry suite green; dual red-team APPROVE (Opus + Sol)
- Full lifecycle on live-RPC anvil-988 fork: deploy→launch→buy→graduate→v3 LP→swap→buyback/burn
- Deploy without code-bearing `STABLE_KEEPER` reverts as designed
- LI.FI bridge Base USDC→USDT0 on 988 quoted live
- Indexer-first radar path + k6 load scripts exist

## Hard GO gates before live factory

From board / `docs/MAINNET_GO_RUNBOOK.md`:

1. Recoverable **Safe** as `STABLE_KEEPER` on 988 (`cast codesize` > 0) — not an EOA
2. Funded **dedicated** deployer key (USDT0 gas) — never the chat/hot wallet
3. Paid `STABLE_RPC_PRIMARY` / `FAILOVER` (archive primary)
4. Indexer host on Fly/Railway/Render — **never demi-poly**
5. DNS / CF custom-domain bind for `stablelaunch.demi.la` (see DNS trap)
6. Explicit DEMI **GO** for broadcast

### CF / edge (do not re-mint tokens blindly)

- Same CF **account** as HL Media (users see hostnames only).
- Web repo already has CF secrets + green deploys (2026-07-25).
- Live: `https://stable-launch-web.christophergervais92.workers.dev` (account-derived sub — never guess `demi-hl`).
- Still need: `STABLE_RPC_*`, `INDEXER_URL`, factory `NEXT_PUBLIC_*` after GO.
- Vault "cfat_ expired" may be stale after green CI.

### Indexer Fly prep

- `fly.toml` in `stable-launch-indexer` (lax, volume `/data`). Empty factory → `live:false` radar OK.
- See indexer README + `docs/PRE_LIVE_OPS.md`.

### DNS trap — never blind-CNAME to workers.dev

`stablelaunch.demi.la` A→demi-poly works. CNAME to workers.dev **without** CF zone + Worker domain bind → **403** on custom Host (probed). Keep VPS A + edge-QA on workers.dev, or CF zone audit → NS → bind. Recipe: `references/dns-cf-workers-trap-2026-07-25.md`. GoDaddy API 401 → mint fresh key before API DNS edits.

## Forbidden

- Launch frontend, indexer, or RPC proxy on demi-poly
- Bundling `stable-agent` into public `stable-launch-web`
- Mainnet broadcast "just to test" when fork rehearsal already passed
- Deploy from the Oracle chat hot wallet

## Safe next steps (default recommendation order)

1. Confirm CF green; set archive RPC secrets; Fly indexer empty-factory + `INDEXER_URL`
2. Wallet physical QA on preview and/or workers.dev
3. Keeper Safe + dedicated deployer
4. CF zone path for custom domain (or leave VPS A)
5. Only then: `docs/MAINNET_GO_RUNBOOK.md`

## Pointers

- Status: `stable-launch/STATUS.md`
- Runbooks: `docs/MAINNET_GO_RUNBOOK.md`, `docs/KEEPER_RUNBOOK.md`, `docs/LAUNCH_TRAFFIC.md`, `docs/PRE_LIVE_OPS.md`
- Notes: `references/testnet-decision-2026-07-25.md`, `references/dns-cf-workers-trap-2026-07-25.md`
