816 lines
45 KiB
Markdown
816 lines
45 KiB
Markdown
# PRE-LAUNCH-CHECKLIST.md
|
||
|
||
**Status:** living document. Last refreshed: 2026-05-24 (Part 122 cp131 — 11 findings shipped end-to-end; backup-retention default + cp131 encryption/push features refreshed).
|
||
|
||
This is the consolidated, ordered list of operator actions
|
||
required (or recommended) before flipping morphit.io from
|
||
pre-launch into a live public instance. Items here are
|
||
either:
|
||
|
||
- **[blocking]** — launch cannot proceed until this is done
|
||
- **[recommended]** — launch can proceed but operator
|
||
experience or user trust suffers without it
|
||
- **[optional]** — improvements that can ship post-launch
|
||
|
||
Every line traces back to a specific Part (audit campaign
|
||
turn) that introduced or refined the action. If an item
|
||
is closed in a later Part, this file is updated **in the
|
||
same turn** as the closing change — never trailing.
|
||
|
||
Memory #5 makes this rule explicit: "All files kept current
|
||
in the same work unit as code changes — docs, ADRs, brag
|
||
list, FAQs, locale JSON, CI config, etc. No trailing stale
|
||
files." This checklist is included in that rule: any Part
|
||
that closes an item must update this file in the same turn.
|
||
Any Part that ADDS an operator action must also update this
|
||
file in the same turn.
|
||
|
||
---
|
||
|
||
## A. Account setup (one-time, before first broadcast)
|
||
|
||
- [ ] **[blocking]** Generate the `@morphit` Blurt account
|
||
if it doesn't already exist. Posting key stays on
|
||
the operator's personal laptop, OFF the morphit.io
|
||
production server. This key signs the
|
||
`morphit_release_v1` ops that pin the canonical
|
||
treasury addresses on chain. *(Origin: Part 106.)*
|
||
|
||
- [ ] **[blocking]** Generate the `@morphit-relay` Blurt
|
||
account. Active key is encrypted by the ops-cli init
|
||
wizard (Section C below) into
|
||
`apps/relay/keystore.json` (or `.wif`), read by the
|
||
relay process for account creation, operator payouts,
|
||
and all relay broadcasts. *(Origin: ADR-0010 §3;
|
||
keystore path corrected to match ops-cli init wizard
|
||
output, Part 122 cp16.)*
|
||
|
||
- [ ] **[blocking]** Generate the canonical BTC treasury
|
||
address. Native segwit (`bc1q...`) recommended.
|
||
Seed backed up offline; spending key never reaches
|
||
the morphit.io production server. *(Origin:
|
||
Part 106.)*
|
||
|
||
- [ ] **[blocking]** Generate the canonical XMR treasury
|
||
wallet. Primary address (`4...`, 95 chars) is the
|
||
only piece needed for production — **no private
|
||
view key required** since Part 108++. Seed backed
|
||
up offline. End-to-end sanity check: after the
|
||
indexer is running with the address configured,
|
||
have a trusted contact send a small test payment
|
||
with a tx_proof and submit it through the real
|
||
Morphit UI. *(Origin: Part 106; view-key
|
||
requirement removed in Part 108++; previous
|
||
diagnostic script retired in Part 110.)*
|
||
|
||
- [ ] **[recommended]** Generate the `@morphit-fees`
|
||
Blurt account if you want a distinct treasury
|
||
account from `@morphit`. Used as the `fee_recipient`
|
||
in operator-config; receives BLURT-paid listing fees.
|
||
*(Origin: Part 106; defaults to `@morphit-fees`.)*
|
||
|
||
- [ ] **[blocking]** **Fund the `@morphit-relay` account
|
||
with starter BLURT before launch.** The relay
|
||
pays for these BLURT-cost activities:
|
||
- **Account creation (OPERATIONS §2)** — at
|
||
signup time the relay broadcasts a direct
|
||
`account_create` op and pays the chain's
|
||
`account_creation_fee` (currently **~100
|
||
BLURT**, witness-set) **inline** from its
|
||
liquid balance. There is no pre-minting —
|
||
Blurt disabled `claim_account` /
|
||
`create_claimed_account` at hard fork 2, so
|
||
Account Creation Tokens no longer exist.
|
||
Operator-side, the cost is "fund the relay
|
||
enough to cover the ~100 BLURT fee for each
|
||
expected signup."
|
||
- **Welcome bonus** — 10 BLURT liquid + 10
|
||
BLURT vested per user on first feedback.
|
||
Paid at the moment the user earns it from
|
||
the relay's running balance.
|
||
- **Loyalty BP delegation** — small (1 BP →
|
||
~1 BLURT-equivalent) granted on first
|
||
verified BLURT-paid fee.
|
||
- **Low-balance auto-refill** — refills
|
||
active users who run critically low on
|
||
BLURT (default 1 BLURT per refill).
|
||
- **Routine ops** — chat-identity registrations,
|
||
feedback ops, signup-failure compensation;
|
||
sub-BLURT each.
|
||
|
||
Realistic sizing (~100 BLURT creation fee per
|
||
expected signup, plus running bonuses/refills):
|
||
|
||
| Expected signups | Suggested float |
|
||
|---|---|
|
||
| Quiet soft-launch (~5 testers) | **~700 BLURT** |
|
||
| First-week ~50 users | **~6,000 BLURT** |
|
||
| First-week ~100 users | **~12,000 BLURT** |
|
||
|
||
The ~100 BLURT/signup creation fee dominates and
|
||
is the load-bearing number.
|
||
Top-ups any time without restart — the relay
|
||
checks its own balance on every signup and
|
||
emits `operator_balance_low` log lines when
|
||
thin. See OPERATIONS §0a + §1 + §2 for the
|
||
full breakdown and the recurrent-transfer
|
||
top-up mechanism.
|
||
|
||
**Don't get caught short**: an operator who
|
||
funds 250 BLURT (the old sizing-table
|
||
conservative figure, since corrected) cannot
|
||
cover the creation fee for even 3 signups, let
|
||
alone a meaningful launch.
|
||
|
||
*(Origin: Part 110; sizing figures corrected
|
||
Part 112 after spotting the 1→100 BLURT
|
||
error. The Part-112 mechanism note described the
|
||
then-current ACT model (`create_claimed_account`);
|
||
that was superseded at beta.28 / cp329 — the relay
|
||
now uses a direct `account_create` op with the fee
|
||
paid inline.)*
|
||
|
||
- [ ] **[blocking]** **Fund the `@morphit` account with
|
||
~10 BLURT before launch.** Small fixed cost;
|
||
not signup-rate-dependent. `@morphit` is the
|
||
trust-anchor account that signs the chain-
|
||
pinned `morphit_release_v1` op (canonical
|
||
BTC/XMR treasury addresses). Each op consumes
|
||
BLURT mana; ~10 BLURT covers many years of
|
||
releases with comfortable headroom.
|
||
|
||
The **warrant canary** is a separate primitive
|
||
— a PGP-signed static file at `/canary.txt`
|
||
regenerated weekly by `scripts/canary/generate.sh`
|
||
and signed by the operator's release PGP key
|
||
(see OPERATIONS §36). The canary does NOT
|
||
consume `@morphit` BLURT; it lives off-chain
|
||
and uses a PGP keypair.
|
||
|
||
*(Origin: Part 112 — gap noticed when listing
|
||
the three Morphit accounts and only the relay
|
||
had explicit funding guidance. Updated cp131
|
||
HIGH-006 — removed misleading reference to a
|
||
non-existent `morphit_warrant_canary_v1` chain
|
||
op.)*
|
||
|
||
- [ ] **[recommended]** Confirm the `@morphit-fees`
|
||
account exists on chain (whether you use the
|
||
default or a custom name). This account
|
||
*receives* BLURT-paid listing fees and has
|
||
**no signing key on any production box** — it
|
||
is genuinely receive-only. No upfront BLURT
|
||
funding required, but the account itself must
|
||
exist before any fee transfer tries to deliver
|
||
to it. *(Origin: Part 110.)*
|
||
|
||
- [ ] **[recommended]** Review the listing fee USD
|
||
target and fallback BLURT/USD price. The wizard
|
||
asks for these during `morphit-ops init`; defaults
|
||
are $0.25 USD listing fee and $0.002 fallback
|
||
BLURT price. Re-confirm both still match your
|
||
operator intent before launch — BTC/XMR prices
|
||
drift, so the BTC sat and XMR piconero amounts
|
||
computed at wizard-run time may be stale by
|
||
launch day. Quick refresh:
|
||
```
|
||
morphit-ops edit → Listing fee + fallback BLURT price
|
||
```
|
||
The wizard re-fetches live Coingecko prices and
|
||
recomputes amounts targeting your USD value.
|
||
*(Origin: Part 110.)*
|
||
|
||
- [ ] **[blocking]** Set `MORPHIT_INSTANCE_OPERATOR_TAG`
|
||
to your instance's operator tag. Canonical
|
||
morphit.io uses `morphit`. Community operators
|
||
pick their own (e.g. `example-community`). The
|
||
wizard captures this at init time (step 16) and
|
||
writes it to `morphit.config.env`.
|
||
|
||
**Without this set correctly, your relay queues
|
||
nothing — every chain op looks like it belongs
|
||
to a different operator, and the conservative
|
||
default ("if I don't know who I am, I pay for
|
||
nothing") engages.**
|
||
|
||
This is the gate that makes Morphit's federation
|
||
cost-attribution work: your relay pays only for
|
||
ops carrying your operator tag. Other operators
|
||
see those ops and skip the payout queue insert,
|
||
so no double-pay across the federation.
|
||
*(Origin: Part 111.)*
|
||
|
||
- [ ] **[blocking — community operators only]**
|
||
Register your operator tag on chain via
|
||
`morphit_operator_register_v1`. First-come-
|
||
first-served on the tag value; once claimed, no
|
||
other operator can use it. Without on-chain
|
||
registration, your 90% operator-payout share
|
||
cannot be attributed even if everything else
|
||
is set up correctly.
|
||
|
||
Canonical morphit.io is already registered with
|
||
tag `morphit`; this step applies only to
|
||
community operators standing up new instances.
|
||
Use the wizard step 16 to pick + commit your
|
||
tag; broadcast the registration op separately
|
||
after the wizard completes. Document for your
|
||
operator-directory listing. *(Origin: Part 111.)*
|
||
|
||
## B. First-time chain broadcasts
|
||
|
||
- [ ] **[blocking]** Broadcast the first
|
||
`morphit_release_v1` op with the `treasury` block
|
||
containing:
|
||
- `btc.address` and `btc.satoshis`
|
||
- `xmr.address` and `xmr.piconero`
|
||
|
||
The builder script
|
||
`apps/indexer/scripts/release-build-payload.ts`
|
||
enforces "no viewkey field" defense-in-depth. The
|
||
op is signed by `@morphit`'s posting key from the
|
||
operator's personal off-server machine. Build it,
|
||
preview it, then sign + broadcast it with the
|
||
laptop-only helper (masked key prompt, never stored;
|
||
see OPERATIONS §40.6). The BTC/XMR treasury addresses
|
||
are pre-filled from the canonical treasury (cp315), so
|
||
you only supply the version, the SRI hash manifest
|
||
(built in §E), and your endpoints file:
|
||
```
|
||
# 1. Build the frontend + the SRI release manifest (§E):
|
||
cd apps/web && npm run build && \
|
||
node scripts/build-manifest.mjs --release-json \
|
||
--prefix index.html --prefix service-worker --prefix _app/immutable/entry/
|
||
cd ../..
|
||
|
||
# 2. Build the release payload (treasury pre-filled),
|
||
# pre-loading the manifest/version (cp436 — endpoints
|
||
# are no longer pinned on-chain; omit the endpoints file).
|
||
# (< /dev/null keeps it non-interactive so the
|
||
# redirected stdout is clean JSON, not prompts):
|
||
MORPHIT_BUILD_VERSION=<semver> \
|
||
MORPHIT_BUILD_HASH_MANIFEST_FILE=apps/web/build-manifest.release.json \
|
||
npx tsx apps/indexer/scripts/release-build-payload.ts < /dev/null > release.json
|
||
|
||
# 3. Preview, then sign + broadcast (masked key):
|
||
npx tsx apps/indexer/scripts/release-broadcast.ts release.json --dry-run
|
||
npx tsx apps/indexer/scripts/release-broadcast.ts release.json
|
||
```
|
||
*(Origin: Part 106 + Part 107 + Part 108++; broadcast
|
||
helper cp317; SRI manifest pipeline fix cp319.)*
|
||
|
||
- [ ] **[recommended]** Verify federation propagation by
|
||
polling each peer's `/v1/release.treasury`. Confirm
|
||
every response shows the same canonical address+amount
|
||
AND that none of them surface a `viewkey` field.
|
||
*(Origin: Part 107 + Part 108++.)*
|
||
|
||
- [ ] **[blocking]** Broadcast an operator registration
|
||
op (`morphit_operator_register_v1`) for any
|
||
operator_tag this instance will use. Tags are
|
||
first-come-first-served; pick before community
|
||
operators do. *(Origin: ADR-0011 operator-earnings
|
||
pipeline.)*
|
||
|
||
## C. Operator-config files (on the morphit.io production box)
|
||
|
||
- [ ] **[blocking]** Run the setup wizard:
|
||
`npx morphit-ops init`. As of Part 122 cp22+ the wizard
|
||
covers ~23 prompts including the fee-verifier
|
||
explorer URLs (BTC + XMR) and chat-link explorer
|
||
URLs (BTC + XMR + BCH + LTC + DASH + DOGE + ZEC + ARRR + DCR + SOL + ETH + XRP; USDT, USDC, DAI have per-network explorers configured separately) with live health-checks,
|
||
plus the trade-only asset policy step. (Exact
|
||
count drifts as we add operator-config surface;
|
||
see `apps/ops-cli/src/init/steps.ts` for the
|
||
authoritative list — `TOTAL_STEPS` constant.) Writes:
|
||
- `morphit.config.env` (allowlisted user-tunables)
|
||
- `morphit.env` (critical infrastructure)
|
||
- `apps/relay/keystore.json` or `.wif` (posting key)
|
||
- Optional backup of `morphit.env`
|
||
|
||
All four files set to mode 0600. *(Origin: ops-cli
|
||
init wizard, extended in Part 109; step-count
|
||
audit Part 119.)*
|
||
|
||
- [ ] **[blocking]** Verify both env files load cleanly
|
||
by starting the indexer briefly and watching for
|
||
Zod config-validation errors:
|
||
`cd apps/indexer && timeout 5 npm run start || true`.
|
||
Repeat for the relay:
|
||
`cd apps/relay && timeout 5 npm run start || true`.
|
||
Both apps' `loadConfig()` run synchronously via Zod
|
||
schemas before any side effects — any misconfiguration
|
||
shows up as a `ZodError` in the first ~100 ms of stderr.
|
||
No `--dry-run` flag exists on either; a 5-second
|
||
`timeout` is the simplest grandma-friendly way to
|
||
exercise validation without staying connected to
|
||
chain. *(Origin: ops-cli init, post-Part-106 hardening;
|
||
Part 119 audit corrected the nonexistent `--dry-run`
|
||
flag reference; Part 122 cp16 walkthrough extended
|
||
validation to the relay env after the cp16 VAPID
|
||
walkthrough showed how easily a relay-env gap can
|
||
hide.)*
|
||
|
||
- [ ] **[blocking if running behind a reverse proxy]** Verify
|
||
`MORPHIT_RELAY_TRUSTED_PROXY_IPS` in `/etc/morphit/relay.env`
|
||
matches your actual reverse-proxy posture. §32 CRITICAL:
|
||
mis-setting this is the difference between functional
|
||
per-IP rate limiting and trivially-spoofable signups.
|
||
- If you run BunkerWeb colocated on the same host (the
|
||
canonical `ops/bunkerweb/` deploy), set to the
|
||
Docker bridge subnet `172.20.0.0/16` (or whatever the
|
||
compose pins as the BunkerWeb network).
|
||
- If you run nginx/Caddy/another proxy on the same host,
|
||
set to `127.0.0.1` (loopback only).
|
||
- If your relay is internet-facing (no proxy), leave UNSET
|
||
(default empty — uses socket peer IP directly).
|
||
Verify by sending a request with a forged `X-Forwarded-For:
|
||
1.2.3.4` header from a NON-trusted IP: the relay must
|
||
ignore the header and use the actual peer IP. *(Origin:
|
||
Part 122 cp57 audit surfaced that this knob was in the
|
||
Zod schema but missing from the canonical `relay.env.example`;
|
||
the canonical example now documents it explicitly with
|
||
the misconfiguration risks.)*
|
||
|
||
- [ ] **[recommended for production deploys]** Review the squatter-
|
||
defense diamond preset settings if you expect any meaningful
|
||
signup volume. In `/etc/morphit/relay.env`:
|
||
- `MORPHIT_RELAY_SIGNUP_DAILY_CEILING=50` (default; raise
|
||
only if you've measured legitimate signup rate above this)
|
||
- `MORPHIT_RELAY_CREATE_RATE_PER_HOUR=5` (per-IP)
|
||
- `MORPHIT_RELAY_CREATE_RATE_PER_DAY=2` (per-IP)
|
||
- `MORPHIT_RELAY_CREATE_SPACING_MINUTES=60` (per-IP)
|
||
- `MORPHIT_RELAY_HIGHVALUE_NAME_POLICY=strict` (or `flag`/`off`)
|
||
- `MORPHIT_RELAY_HIGHVALUE_SHORT_NAME_THRESHOLD=4`
|
||
- `MORPHIT_RELAY_SEQUENTIAL_DETECTOR_ENABLED=true`
|
||
See `docs/OPERATIONS.md §38.7` for the diamond-hardened
|
||
preset rationale and `docs/RUN-A-MORPHIT-NODE.md §"Diamond-
|
||
hardened squatter defense"` for the tactical guide. Every
|
||
successful squatter signup costs the relay ~100 BLURT — the
|
||
tightened defaults are worth their friction. *(Origin: Part
|
||
122 cp57 audit; these knobs were already in the Zod schema
|
||
but operators needed them surfaced as a pre-launch decision.)*
|
||
|
||
- [ ] **[blocking]** Run the static smoke suite and
|
||
confirm it returns clean. From the repo root:
|
||
`bash scripts/run-smokes.sh`. Expected output:
|
||
`Total: 3,327+ scenarios passed, 0 runners failed`
|
||
(the "0 runners failed" is the load-bearing assertion —
|
||
the scenario count is a moving lower bound that ticks up
|
||
as smokes are added each release; baseline-source-of-truth
|
||
is the cp27 floor of 3,327, with subsequent checkpoints
|
||
adding scenarios on top: cp30 USDC, cp31 DAI, cp32 icon-
|
||
coverage + payment-method-i18n-parity, cp33 DOGE, cp34
|
||
narrow-union-parity, cp39 ZEC, cp41 ARRR, cp43 DCR, cp44
|
||
LL #52 workspace-typecheck, cp45 SOL, cp46 asset-payload-
|
||
precision-parity, cp47 ETH, cp48-O1 stand-in meta-assertion,
|
||
cp49 XRP + cp49-O2 handler-test-stand-in, cp50-O3 per-asset-
|
||
rss-feed-parity + 31 jitter unit tests, cp51-O4 category-b-
|
||
descriptions-parity + cp51-O5 faq-per-tradable-asset-parity
|
||
+ 3 backfilled FAQs × 10 locales, cp52-O6 ansible-env-
|
||
template-required-vars, cp53-O7 operator-doc-per-asset-coverage
|
||
+ 14 doc-drift inline fixes, cp54-O8 what-is-asset-faq-native-
|
||
locale-floor + 60 native ES/FR/DE translations, cp55-O9 per-
|
||
asset-key-family-native-locale-floor registry + 33 more native
|
||
translations (93 total Memory #29 catch-up), cp56-O10 operator-
|
||
doc-per-asset-config-example-coverage (shallow-mention floor),
|
||
cp57-O11 env-example-schema-parity (bidirectional) + 9 indexer/
|
||
relay knob-doc additions (incl. TRUSTED_PROXY_IPS and squatter-
|
||
defense diamond preset), cp80-O26 long-form-en-fallback-floor
|
||
(1,758 translation pairs/CI run), cp81-O27 service-worker-single-
|
||
registration (7 checks), cp81-O28 short-form-en-fallback-floor
|
||
(4,770 translation pairs/CI run), cp111-O29 brag-list-claim-
|
||
parity-smoke (81 scenarios: file paths, op IDs, env-vars, and
|
||
asset/locale/ADR/brag-footer count anchors across the three
|
||
marketing-class docs; mutation-tested across all 7 drift
|
||
classes), cp112-O30 seo-url-consistency-smoke (366 scenarios
|
||
verifying canonical/hreflang/sitemap URLs match byte-for-byte;
|
||
catches the cp112 hreflang-form drift class), cp112-O31
|
||
og-image-freshness-smoke (6 scenarios catching PNG-older-
|
||
than-SVG drift after the cp112 PNG fallback shipped). The
|
||
exact current total is whatever `run-smokes.sh` prints
|
||
against the repo state you're running; what you're verifying
|
||
is that the count is ≥ 3,327 AND that zero runners failed).
|
||
|
||
If you see several runners fail with
|
||
`ERR_MODULE_NOT_FOUND` errors all referencing a
|
||
`@morphit/*` package, you skipped the
|
||
`npm install` step (or did it from inside one of
|
||
the workspace sub-directories instead of the
|
||
repo root). Workspace symlinks live under
|
||
`node_modules/@morphit/*` and are only created
|
||
by an install run from the root. Fix:
|
||
`cd ~/morphit && npm install --no-audit --no-fund`,
|
||
then re-run the smoke suite. This is NOT a code
|
||
regression — pure environment setup. *(Origin:
|
||
Part 121 audit found this drift while extending
|
||
smoke coverage to the asset-registry expansion.)*
|
||
|
||
- [ ] **[recommended]** If you want priority-#2 maximum
|
||
independence, self-host a `monero-block-explorer`
|
||
+ `monerod` Docker stack and point
|
||
`MORPHIT_INDEXER_XMR_EXPLORER_URLS` at localhost.
|
||
~50 GB disk, ~3-7 days initial monerod sync. See
|
||
`docs/OPERATIONS.md §40.4`. Operator confirmed
|
||
OFF the table for the initial launch (cost), but
|
||
remains a documented option for later. *(Origin:
|
||
Part 108++.)*
|
||
|
||
- [ ] **[blocking]** Decide your trade-only-asset operator
|
||
stance. The canonical morphit.io ships USDT, USDC, DAI,
|
||
BCH, LTC, DASH, DOGE, ZEC, ARRR, DCR, SOL, ETH, XRP, and BARTER (goods/services — the
|
||
one non-crypto tradable "asset"; disable-able the same way) enabled by default; alternative
|
||
instances may want to disable one or more instance-wide
|
||
on philosophical (centralization, fork preference),
|
||
regulatory, or audience-specialization grounds.
|
||
|
||
**The wizard handles this for you.** `morphit-ops init`
|
||
step 13 "Trade-only asset policy" (Part 122 cp22) walks
|
||
through every shipped trade-only asset and asks
|
||
per-ticker whether to enable it. Default for each is YES.
|
||
Pick "n" at the prompt to disable that asset; the wizard
|
||
emits the correct `MORPHIT_INDEXER_DISABLED_ASSETS=` line
|
||
into `morphit.config.env` for you. Re-run the wizard
|
||
later to change your mind without touching the env file
|
||
by hand.
|
||
|
||
Equivalent post-deploy env-edit per-asset options:
|
||
1. Accept everything (default — no config change).
|
||
2. Refuse USDT — set
|
||
`MORPHIT_INDEXER_DISABLED_ASSETS="USDT"`.
|
||
3. Refuse USDC — set
|
||
`MORPHIT_INDEXER_DISABLED_ASSETS="USDC"`.
|
||
4. Refuse DAI — set
|
||
`MORPHIT_INDEXER_DISABLED_ASSETS="DAI"`.
|
||
5. Refuse BCH — set
|
||
`MORPHIT_INDEXER_DISABLED_ASSETS="BCH"`.
|
||
6. Refuse LTC — set
|
||
`MORPHIT_INDEXER_DISABLED_ASSETS="LTC"`.
|
||
7. Refuse DASH — set
|
||
`MORPHIT_INDEXER_DISABLED_ASSETS="DASH"`.
|
||
8. Refuse DOGE — set
|
||
`MORPHIT_INDEXER_DISABLED_ASSETS="DOGE"`.
|
||
9. Refuse BARTER (goods/services — e.g. a crypto-only
|
||
instance) — set
|
||
`MORPHIT_INDEXER_DISABLED_ASSETS="BARTER"`.
|
||
10. Refuse multiple —
|
||
`MORPHIT_INDEXER_DISABLED_ASSETS="USDT,USDC,DAI,BCH,LTC,DASH,DOGE,ZEC,ARRR,DCR,SOL,ETH,XRP,BARTER"`.
|
||
|
||
Federation note: disabling an asset means your own
|
||
users cannot POST orders for it; you'll still see
|
||
those orders from peer instances in read-only
|
||
orderbook feeds (chain history is shared).
|
||
|
||
Whichever stance you take, document it publicly so
|
||
users know what your instance offers. Memory #25
|
||
(default-on + operator override for new assets),
|
||
ADR-0023 (USDT), ADR-0024 (BCH), ADR-0025 (LTC),
|
||
ADR-0027 (DASH), ADR-0028 (USDC), ADR-0029 (DAI),
|
||
ADR-0030 (DOGE), ADR-0031 (ZEC), ADR-0032 (ARRR), ADR-0033 (DCR), ADR-0034 (SOL), ADR-0035 (ETH), ADR-0036 (XRP), and Part 122 cp22 (wizard step) explain
|
||
the design. *(Origin: Part 121 cp3 USDT integration,
|
||
Part 122 cp21 BCH integration, Part 122 cp22 wizard
|
||
step, Part 122 cp24 LTC integration, Part 122 cp27 DASH
|
||
integration, Part 122 cp30 USDC integration, Part 122
|
||
cp31 DAI integration, Part 122 cp33 DOGE integration, Part 122 cp39 ZEC integration, Part 122 cp41 ARRR integration, Part 122 cp43 DCR integration, Part 122 cp45 SOL integration, Part 122 cp47 ETH integration, Part 122 cp49 XRP integration.)*
|
||
|
||
- [ ] **[blocking]** Decide BCH chat-link explorer URL.
|
||
Default `https://blockchair.com/bitcoin-cash/transaction/{txid}`
|
||
is fine for most operators. Override via
|
||
`MORPHIT_FRONTEND_BCH_CHAT_LINK_URL` if you prefer a
|
||
different explorer or run your own. See
|
||
`docs/OPERATIONS.md` §"BCH chat-link explorer URL
|
||
override" for the alternatives surveyed at cp21
|
||
addition time. *(Origin: Part 122 cp21 BCH integration.)*
|
||
|
||
- [ ] **[blocking]** Decide LTC chat-link explorer URL.
|
||
Default `https://litecoinspace.org/tx/{txid}` is fine for
|
||
most operators. Override via `MORPHIT_FRONTEND_LTC_CHAT_LINK_URL`
|
||
if you prefer a different explorer or run your own. See
|
||
`docs/OPERATIONS.md` §"LTC chat-link explorer URL
|
||
override" for the alternatives surveyed at cp24
|
||
addition time. *(Origin: Part 122 cp24 LTC integration.)*
|
||
|
||
- [ ] **[blocking]** Decide DASH chat-link explorer URL.
|
||
Default `https://insight.dash.org/insight/tx/{txid}`
|
||
(official Dash project Insight, community-led,
|
||
open-source) is fine for most operators. Override via
|
||
`MORPHIT_FRONTEND_DASH_CHAT_LINK_URL` if you prefer a
|
||
different explorer or run your own. See
|
||
`docs/OPERATIONS.md` §"DASH chat-link explorer URL
|
||
override" for the 9 alternatives surveyed at cp27
|
||
addition time. *(Origin: Part 122 cp27 DASH integration.)*
|
||
|
||
- [ ] **[blocking]** Decide DOGE chat-link explorer URL.
|
||
Default `https://blockchair.com/dogecoin/transaction/{txid}`
|
||
is fine for most operators. Override via
|
||
`MORPHIT_FRONTEND_DOGE_CHAT_LINK_URL` if you prefer a
|
||
different explorer or run your own (e.g.
|
||
`https://dogechain.info/tx/{txid}`, or a self-hosted
|
||
Iquidus instance). *(Origin: Part 122 cp33 DOGE integration;
|
||
ADR-0030.)*
|
||
|
||
- [ ] **[blocking]** Decide ZEC chat-link explorer URL.
|
||
Override `MORPHIT_FRONTEND_ZEC_CHAT_LINK_URL` if you prefer a
|
||
different default from the bundled `mainnet.zcashexplorer.app`.
|
||
Operator's 7-explorer survey at cp39 (mainnet.zcashexplorer.app,
|
||
blockchair.com/zcash, zcashinfo.com, 3xpl.com/zcash,
|
||
blockexplorer.one/zcash/mainnet, zcash.tokenview.io,
|
||
cipherscan.app) is documented in ADR-0031. *(Origin: Part 122
|
||
cp39 ZEC integration; ADR-0031.)*
|
||
|
||
- [ ] **[blocking]** Decide ARRR chat-link explorer URL.
|
||
Override `MORPHIT_FRONTEND_ARRR_CHAT_LINK_URL` if you prefer a
|
||
different default from the bundled `explorer.piratechain.com`.
|
||
Operator's 3-explorer survey at cp41 (explorer.piratechain.com,
|
||
pirate.explorer.dexstats.info, blockchain.com/explorer/assets/arrr)
|
||
is documented in ADR-0032. *(Origin: Part 122 cp41 ARRR
|
||
integration; ADR-0032.)*
|
||
|
||
- [ ] **[blocking]** Decide DCR chat-link explorer URL.
|
||
Override `MORPHIT_FRONTEND_DCR_CHAT_LINK_URL` if you prefer a
|
||
different default from the bundled `dcrdata.decred.org`.
|
||
Operator's 4-explorer survey at cp43 (dcrdata.decred.org,
|
||
blockchain.com/explorer/assets/dcr, dcr.tokenview.io,
|
||
bitinfocharts.com/decred/) is documented in ADR-0033.
|
||
*(Origin: Part 122 cp43 DCR integration; ADR-0033.)*
|
||
|
||
- [ ] **[blocking]** Decide SOL chat-link explorer URL.
|
||
Override `MORPHIT_FRONTEND_SOL_CHAT_LINK_URL` if you prefer a
|
||
different default from the bundled `explorer.solana.com`.
|
||
Operator's 5-explorer survey at cp45 (explorer.solana.com,
|
||
solscan.io, solanabeach.io, oklink.com/solana, solana.fm —
|
||
unreachable at survey time) is documented in ADR-0034.
|
||
*(Origin: Part 122 cp45 SOL integration; ADR-0034.)*
|
||
|
||
- [ ] **[blocking]** Decide ETH chat-link explorer URL.
|
||
Override `MORPHIT_FRONTEND_ETH_CHAT_LINK_URL` if you prefer a
|
||
different default from the bundled `eth.blockscout.com`.
|
||
Operator's 9-explorer survey at cp47 (eth.blockscout.com,
|
||
etherscan.io, blockchair.com/ethereum, ethplorer.io,
|
||
oklink.com/ethereum, blockchain.com/explorer/assets/eth,
|
||
blockexplorer.one/ethereum/mainnet, routescan.io,
|
||
beaconcha.in — consensus-layer only) is documented in
|
||
ADR-0035.
|
||
*(Origin: Part 122 cp47 ETH integration; ADR-0035.)*
|
||
|
||
- [ ] **[blocking]** Decide XRP chat-link explorer URL.
|
||
Override `MORPHIT_FRONTEND_XRP_CHAT_LINK_URL` if you prefer a
|
||
different default from the bundled `livenet.xrpl.org`.
|
||
Operator's 5-explorer survey at cp49 (livenet.xrpl.org,
|
||
xrpscan.com, bithomp.com, blockchair.com/xrp-ledger,
|
||
blockexplorer.one/xrp/mainnet) is documented in ADR-0036.
|
||
*(Origin: Part 122 cp49 XRP integration; ADR-0036.)*
|
||
|
||
- [ ] **[recommended, non-blocking]** **VAPID keypair for
|
||
Web Push notifications** (Part 122 cp13). Without
|
||
this, push notifications are disabled instance-wide
|
||
and users on your instance see "Not supported on this
|
||
device" in Settings → Notifications. In-tab ambient
|
||
channels (title-bar badge, favicon dot, OS native
|
||
notifications when the tab is open, audio cue,
|
||
vibration) keep working without VAPID.
|
||
|
||
One-time setup:
|
||
```
|
||
bash scripts/generate-vapid-keys.sh
|
||
```
|
||
Append the three printed lines to
|
||
`/etc/morphit/relay.env` (replace the placeholder
|
||
mailto: address with a real one — push services
|
||
contact you there if something goes wrong).
|
||
Restart the relay.
|
||
|
||
The relay will boot-log either
|
||
`push_enabled` (success) or
|
||
`push_disabled_no_vapid_keys` (missing). The
|
||
worker's drain interval is tunable via
|
||
`MORPHIT_RELAY_PUSH_POLL_INTERVAL_MS` (default
|
||
2000). Subscribe-endpoint authentication
|
||
requires a valid posting-key signature by default
|
||
(Part 122 cp14, `MORPHIT_RELAY_PUSH_REQUIRE_SIGNED=true`).
|
||
Full operator reference at
|
||
`docs/OPERATIONS.md` §42 and
|
||
`docs/RUN-A-MORPHIT-NODE.md` Web Push subsection.
|
||
*(Origin: Part 122 cp13–cp14.)*
|
||
|
||
## D. Infrastructure
|
||
|
||
- [ ] **[blocking]** Postgres reachable from the morphit
|
||
processes. Database URL configured in both
|
||
indexer and relay envs. Initial schema applied
|
||
via the indexer's auto-migrate on first boot
|
||
(currently `schema_migrations.version = 1`, which
|
||
under the May 2026 audit and the cp131 DEEP-002
|
||
framing extension is the **pre-launch baseline**
|
||
that grows in place: it collapses historical
|
||
versions 1-35 into the single canonical
|
||
`apps/indexer/src/db/schema.sql`; the collapsed
|
||
schema contains every v33+ feature originally
|
||
added incrementally — `push_subscriptions` +
|
||
`push_pending` tables, the `locale` column on
|
||
push_subscriptions, the composite
|
||
push_subscriptions(account, created_at DESC) index,
|
||
the `extension_count` + `last_extended_at`
|
||
columns on featured_slot_bids for the anti-snipe
|
||
soft-close auction rule, ix_featured_bids_expires
|
||
index for the snipe-window check,
|
||
review_concentration (cp123 H2), and
|
||
price_drift_baseline (cp127 defense B).
|
||
Downstream code that checks "is vN applied?" via
|
||
`subsumesVersions` still works for any
|
||
v ∈ {2..35}. The v1 baseline grows in place
|
||
until 1.0.0 launch; the first separate additive
|
||
migration to be assigned an integer version will
|
||
land at launch. No further collapse should happen
|
||
until well after 1.0.0 ships.). *(Origin:
|
||
ADR-0001 schema management; collapsed-schema
|
||
framing refreshed Part 122 cp82; subsumesVersions
|
||
extended 2..27 → 2..35 + framing reconciled with
|
||
schema.sql section markers Part 122 cp131
|
||
DEEP-002.)*
|
||
|
||
- [ ] **[recommended]** Enable the daily DB backup
|
||
scheduled by the wizard (off by default; opt-in
|
||
during setup). Retention configurable via
|
||
`RETAIN_DAYS` in `backup.env`; default 30 days.
|
||
The shipped script also supports optional age
|
||
encryption (set `AGE_RECIPIENT`) and optional
|
||
rsync push to an off-site host (set
|
||
`REMOTE_DESTINATION` + `SSH_KEY`) — see
|
||
`RUN-A-MORPHIT-NODE.md §10` and `OPERATIONS.md §37.12`
|
||
for the recipe. *(Origin: ops-cli init; encryption
|
||
and push features Part 122 cp131 HIGH-001.)*
|
||
|
||
- [ ] **[recommended]** Reverse proxy in front of the
|
||
indexer + frontend with HTTPS termination. Caddy
|
||
or nginx; the wizard doesn't auto-configure this,
|
||
it's deployment-flavor-specific. *(Origin: ops
|
||
runbook.)*
|
||
|
||
- [ ] **[optional]** Tor hidden service, Lokinet, I2P
|
||
.b32 address for privacy-network access. All
|
||
three are operator-configurable in the wizard.
|
||
*(Origin: Part D.5 federation directory + alt-
|
||
network reachability.)*
|
||
|
||
## E. Frontend deployment
|
||
|
||
- [ ] **[blocking]** Build the frontend bundle:
|
||
`cd apps/web && npm run build`. Output goes to
|
||
`apps/web/build/`.
|
||
|
||
- [ ] **[blocking]** Hash the bundle and include the
|
||
hash manifest in the next `morphit_release_v1`
|
||
op so federated frontends can verify integrity.
|
||
`build-manifest.mjs` emits TWO distinct artifacts
|
||
from the same `apps/web/build/` walk — do not mix
|
||
them up:
|
||
```
|
||
# (a) Reproducible-build fingerprint (sha256sum text,
|
||
# for clone-vs-ship diffs — NOT the release op):
|
||
cd apps/web && node scripts/build-manifest.mjs
|
||
|
||
# (b) The ON-CHAIN release hash_manifest (SRI base64
|
||
# JSON, scoped to the tamper-critical BOOTSTRAP — shell +
|
||
# service worker + entry loader — to stay under the indexer's
|
||
# 4 KB per-field JSONB cap):
|
||
cd apps/web && node scripts/build-manifest.mjs \
|
||
--release-json --prefix index.html --prefix service-worker \
|
||
--prefix _app/immutable/entry/
|
||
```
|
||
Artifact (b) writes `apps/web/build-manifest.release.json`
|
||
— a JSON object of `/<served-path>: sha256-<base64>`,
|
||
exactly the shape `@morphit/release-schema` requires and
|
||
the frontend tamper-check (`releaseHashCheck.ts`) verifies
|
||
the running bundle against. Supply it to the release-op
|
||
builder via the `MORPHIT_BUILD_HASH_MANIFEST_FILE` env var
|
||
(see §B for the full broadcast flow). *(Origin: ADR-0007
|
||
chain-pinned hash manifest; build-manifest reference added
|
||
Part 122 cp19; SRI `--release-json` mode + format fix
|
||
cp319.)*
|
||
|
||
- [ ] **[recommended]** Verify your frontend renders
|
||
correctly for ALL 10 locales (en, es, fr, de, it,
|
||
pl, ru, fa, zh-CN, zh-HK) before going live.
|
||
Specifically check the post-order screen at
|
||
`/post` which has the most complex
|
||
locale-dependent UI (per-wallet proof generation
|
||
instructions for XMR, etc.). *(Origin: Memory
|
||
#4 — 10-locale invariant.)*
|
||
|
||
## F. Marketing / outreach (pre-launch but soft-blocking)
|
||
|
||
- [ ] **[recommended]** Launch blog post drafted using
|
||
`MORPHIT-BRAG-LIST.md` as the source-of-truth set
|
||
of claims. Every claim must be either verifiable
|
||
in code or honestly disclosed as backlog. *(Origin:
|
||
Memory #15.)*
|
||
|
||
- [ ] **[recommended]** Matrix channel
|
||
`#agorise:matrix.org` actively monitored, and the
|
||
`@agorise:matrix.org` MXID actively monitored for
|
||
DM security disclosures. *(Origin: Memory facts.)*
|
||
|
||
- [ ] **[optional]** Beta-tester intake form actively
|
||
used. Form is shipped (Memory: "beta-tester
|
||
intake form" completed earlier) — track responses
|
||
and reach out. Verify form is live + collecting
|
||
submissions correctly. *(Origin: pre-launch
|
||
hardening campaign.)*
|
||
|
||
## G. Things explicitly NOT required to launch
|
||
|
||
These are tracked as REVISIT-LIST follow-ups but do not
|
||
block initial launch:
|
||
|
||
- Self-hosted BTC explorer (Esplora) on the morphit.io
|
||
box. Public Esplora explorers (blockstream.info,
|
||
mempool.space) are sufficient for the multi-explorer
|
||
cross-check defaults. *(Operator decision Part 109:
|
||
off the table for now; revisit post-launch.)*
|
||
|
||
- Self-hosted XMR explorer on the morphit.io box. The
|
||
5 verified-compatible public explorers in the default
|
||
config provide adequate cross-check. *(Operator
|
||
decision Part 109: off the table for now; revisit
|
||
post-launch.)*
|
||
|
||
- Per-user explorer preference (Settings page +
|
||
localStorage) for the chat-link feature. Part 109
|
||
shipped the per-OPERATOR override; per-user is a
|
||
natural extension but not required to launch.
|
||
|
||
- Auto-defaulted quorum threshold based on URL count.
|
||
Part 109 ships default 1 (back-compat). A future
|
||
part may bump to `Math.max(1, ceil(N/2))`.
|
||
|
||
## H. Day-0 monitoring checklist (the first 24 hours after launch)
|
||
|
||
> **The full day-zero runbook lives in
|
||
> `docs/LAUNCH-DAY.md`.** The checklist below is the
|
||
> condensed pre-flight; the full doc covers T-minus 24h
|
||
> rehearsals, T-zero procedures, what to watch hour-by-hour,
|
||
> rollback, and end-of-day-zero retrospective.
|
||
>
|
||
> **For days 1–7 after launch, see
|
||
> `docs/POST-LAUNCH-WEEK-ONE.md`.** Covers monitoring
|
||
> cadence, paging thresholds, common week-one situations,
|
||
> and when to dial down to sustainable operations.
|
||
|
||
- [ ] Check `/v1/health` returns 200 every minute.
|
||
- [ ] Check `/v1/release` returns the canonical
|
||
treasury block as broadcast.
|
||
- [ ] Check `journalctl -u morphit-indexer` for any
|
||
ERROR-level lines.
|
||
- [ ] Check Postgres `morphit_indexer_processed_block`
|
||
progresses (each Blurt block advances the
|
||
indexer's pointer; if stuck, RPC issue).
|
||
- [ ] Check the first user signup completes end-to-end
|
||
(registration → relay broadcast → on-chain account
|
||
created → orderbook visible).
|
||
- [ ] Check the first BTC and XMR fee verifications
|
||
complete. XMR fee verifications now require a
|
||
user-supplied per-payment proof (Part 108++) —
|
||
verify the post-order form rendered correctly with
|
||
the proof textarea and per-wallet instructions for
|
||
the first XMR-paying user. Inspect status via:
|
||
`psql -c "SELECT permlink, fee_method, fee_status FROM orders WHERE fee_status IS NOT NULL ORDER BY created_at DESC LIMIT 10;"`.
|
||
Healthy: rows transition from `pending` → `verified`
|
||
within a few minutes of the fee transfer being mined.
|
||
- [ ] Watch the **relay balance** trend. If
|
||
auto-refills are firing on day-zero traffic, the
|
||
relay account drain rate is real; top up
|
||
pre-emptively if you're approaching the
|
||
low-balance threshold.
|
||
- [ ] **[if push enabled]** Watch the `push_pending`
|
||
queue size. Quick check:
|
||
`psql -c 'SELECT COUNT(*) FROM push_pending;'`.
|
||
Healthy: drains to ≤ batch_size (default 50)
|
||
within poll_interval (default 30s). Growing
|
||
unboundedly = worker is wedged (VAPID misconfig,
|
||
web-push library auth failure, or DB lock).
|
||
Cross-reference with the relay's
|
||
`push_sender_tick` log lines. *(Origin: Part 122
|
||
cp16 walkthrough — DD-10 single-relay invariant
|
||
makes queue growth a clean failure signal.)*
|
||
|
||
---
|
||
|
||
## Update history
|
||
|
||
| Part | Date | Change to this file |
|
||
|---|---|---|
|
||
| 122 cp139 | 2026-05-25 | No structural changes. cp139's 32 audit findings (across apps/{matrix-bot,ops-cli,relay,indexer,web} + packages/*) were all internal hardening — no operator-facing surface changes. The smoke battery floor moved from 5,983 → 6,076 with cp139-F-2's 9-scenario PPM-7-{1..9} SSRF regression sentinels. Memory drift caught + corrected: the previously-tracked "standing pre-launch operator action" to rotate `CHANGE_ME_BEFORE_PRODUCTION` was actually closed many checkpoints ago — that string is a DENYLIST entry in `ops/postgres/init.sql:58-65` that REJECTS operator deployment with weak placeholders (it IS the safety feature). cp111 Lesson #1 already documented this for the other 2 items; cp139 closes the third. ALL 3 standing pre-launch operator items are now confirmed SHIPPED. Quintuple→sextuple-pulse stability invariant at 6076/6076. Operators just need to verify zero runners failed. |
|
||
| 122 cp131 | 2026-05-24 | D-section backup item updated: retention default corrected 14→30 days (real default in `ops/backup/backup.env.example`); cp131 HIGH-001 added `AGE_RECIPIENT`/`REMOTE_DESTINATION`/`SSH_KEY` env-var-honored encryption + rsync features to `morphit-backup.sh`, referenced from the item with pointers to RUN-A-MORPHIT-NODE §10 + OPERATIONS §37.12 for the recipe. No new operator action items for cp131 — all 11 findings were code/doc-side closures that landed without operator-facing surface change. Floor of 3,327 still load-bearing — operators just need to verify zero runners failed. Battery is now 5,713/0 across triple-pulse. |
|
||
| 122 cp112 | 2026-05-22 | Section C cumulative cp listing extended with cp112-O30 (`seo-url-consistency-smoke`, 366 scenarios — verifies canonical/hreflang URLs from the helper match the sitemap-builder's URLs byte-for-byte across every indexable route × locale; mutation-tested) + cp112-O31 (`og-image-freshness-smoke`, 6 scenarios — verifies the PNG OG image fallback exists, is 1200×630, is under 5 MB, and is no older than its SVG source). No operator-facing surface changes — both are internal hardening for SEO + share-preview surfaces. Floor of 3,327 still load-bearing — operators just need to verify zero runners failed. |
|
||
| 122 cp111 | 2026-05-22 | Section C scenario-count cumulative checkpoint listing extended to include cp111-O29 (`brag-list-claim-parity-smoke`, 81 scenarios across 7 drift classes — file paths, custom-JSON op IDs, MORPHIT_* env-vars, asset/locale/ADR/brag-footer count anchors; mutation-tested across all 7 classes). No operator-facing surface changes — the smoke is internal hardening for the three marketing-class docs (MORPHIT-BRAG-LIST, README, RELEASE-NOTES). Floor of 3,327 still load-bearing — operators just need to verify zero runners failed. |
|
||
| 122 cp82 | 2026-05-21 | Section C scenario-count cumulative checkpoint listing extended to include cp80-O26 (long-form-en-fallback-floor, 1,758 translation pairs/CI run), cp81-O27 (service-worker-single-registration, 7 checks against the cp81-D22 dual-registration regression), and cp81-O28 (short-form-en-fallback-floor, 4,770 translation pairs/CI run). No new operator action items — cp80/cp81 work is internal hardening + content backlog closure + bug-fix (push notifications were silently broken in production due to dual SW registration; clickPath was an operator-phishing primitive); all fixed without operator-facing surface change. Floor of 3,327 still load-bearing — operators just need to verify zero runners failed. |
|
||
| 122 cp20 | 2026-05-17 | Section C smoke baseline bumped from 3,173 → 3,187 to match the new `version-consistency-smoke` (14 scenarios) shipped this turn. The smoke catches drift between the root `package.json` version, the 9 sub-package versions, the runtime `VERSION`/`INDEXER_VERSION` constants in relay+indexer `/v1/health`, and the example responses in `docs/API.md` + `apps/indexer/README.md` — pre-cp20 those touchpoints had four different version strings, none of them the release tag. All 14 unified to `1.0.0-beta.1` and the smoke is wired into `scripts/run-smokes.sh`. |
|
||
| 109 | 2026-05-10 | Initial consolidated checklist. Items A-H gathered from Parts 106 + 107 + 108++ + 109 operator-action lists in REVISIT-LIST, OPERATIONS.md §40, RUN-A-MORPHIT-NODE.md, and TARBALL.md. Section G "explicitly NOT required" reflects operator decision in Part 109 to defer self-hosted explorers. |
|
||
| 109 | 2026-05-10 | Section G updated mid-Part-109 after the quorum gate and viewkey-env removal landed. Removed the two now-closed items (viewkey removal, quorum) and added two new deferred items (per-user explorer preference, auto-defaulted quorum threshold) per Memory #5 same-turn update rule. |
|
||
| 110 | 2026-05-10 | Section A gained two new items: relay-account funding (`[blocking]`) and fees-account-exists-on-chain (`[recommended]`). Operator-reported gap: previous revisions assumed operators knew the relay needed BLURT upfront; explicit checkbox reduces failed first-day launches. Section A also updated to retire the `verify-xmr-viewkey.ts` reference (script retired Part 110). Section H expanded with reference to `LAUNCH-DAY.md` (new) and `POST-LAUNCH-WEEK-ONE.md` (new) for day-zero and week-one runbooks. |
|
||
| 110 | 2026-05-10 | Section A gained a `[recommended]` "Review listing fee + fallback BLURT price" item. The wizard prompts for these during init, but BTC/XMR prices drift between wizard-run and launch day so a pre-launch re-confirmation is worth doing — `morphit-ops edit → Listing fee + fallback BLURT price` re-fetches live Coingecko prices and recomputes amounts. |
|
||
| 111 | 2026-05-10 | Section A gained two new items for the federation-cost-attribution model: `[blocking]` set `MORPHIT_INSTANCE_OPERATOR_TAG` (canonical morphit.io uses `morphit`; community operators pick their own) and `[blocking — community operators only]` register the tag on chain via `morphit_operator_register_v1`. Without these, the relay queues NO payouts because it can't prove which ops are "ours." |
|
||
| 122 cp19 | 2026-05-17 | Pre-launch dry-run walkthrough surfaced 4 doc gaps: (1) Section A mint-acts invocation used bare `tsx scripts/mint-acts.ts 25` which fails on operator boxes without global tsx; corrected to `npm run mint-acts -- 25` (matching npm script added to `apps/relay/package.json`); (2) Section C smoke baseline bumped from 3,154 → 3,173 to match cp18; (3) Section E added build-manifest script invocation (`node scripts/build-manifest.mjs`) so operators know HOW to produce the hash manifest, not just that they need to; (4) Section H fee-verification check now includes the `psql SELECT permlink, fee_method, fee_status` query so operators can inspect status without spelunking. |
|
||
| 122 cp16 | 2026-05-16 | Sally-operator walkthrough surfaced 4 doc gaps: (1) Section A keystore path was stale (`/etc/morphit/keys/relay-active.key` → corrected to `apps/relay/keystore.{wif,json}` matching ops-cli init); (2) Section C env-load verification now covers relay too, not just indexer; (3) Section C smoke-count baseline bumped from 2,900+ → 3,100+ (cp16 baseline 3,154); (4) Section H Day-0 monitoring gains push_pending queue-health check when push is enabled. Section C VAPID setup step + Section D schema-v33 reference + audit-cp15 refinements landed earlier in cp16. |
|
||
| 119 | 2026-05-11 | Section C wizard step-count corrected (14 → ~17 with disclaimer pointing at `apps/ops-cli/src/init/steps.ts` as the source-of-truth list). Section C also corrected the nonexistent `--dry-run` flag — the indexer has no such flag; use a 5-second `timeout npm run start` to exercise Zod env validation instead. Section D schema version updated v29 → v31 to reflect Part 113's Signal C addition. |
|