Build log · BTC Market Monitor

From one laptop to btcmm.app in eight days

Between October 1 and October 8, 2026, a paper-trading bot running on a single laptop became a monitored, test-gated, cloud-hosted web app with sign-in and its own domain. This page traces that change through 135 recorded change requests (CRs).

System
Kalshi 15-min crypto paper bot + dashboard
Window
2026-10-01 → 2026-10-08
Changes
CR-0001 → CR-0135
Release
1.1.2-beta
Trading
Paper only, no live order path
135change requests, each with a record and release note
501automated tests: 278 Python, 159 Vitest, 64 Playwright
3test layers: logic, screen components, full browser runs
8days from laptop to a public domain
Section A · System context

Before and after

October 1 · everything on one machine

As found
Users browser / phone Sign-in gate one shared check in front of the whole site ONE LAPTOP · ALSO AN EVERYDAY MACHINE Dashboard web API + React app Paper bot market feeds Database growing about 1 GB a day Releases copied and restarted by hand no automated tests Backups manual script Monitoring none: problems found by looking Single point of failure restarts, sleep and clock drift all reached the live site
  • No automated tests in CI (the checks GitHub runs on every change), and no alerting.
  • The bot, the data and the public site all depended on one laptop staying awake.

October 8 · a small, managed cloud system

As built
Users admin + viewers btcmm.app global network · HTTPS · abuse protection Sign-in service email code, no passwords secure tunnel CLOUD SERVER · DEDICATED TO THE APP Dashboard checks sign-in on every request Paper bot auto-restarts Database 7 days detailed + archive Secrets managed, encrypted Health monitoring automatic alerts by email Automated backups scheduled snapshots Services restart themselves · server updates run automatically · bot restarts only between trading windows Code repository + pipeline tests must pass before anything ships Laptop · development only code, local checks, Claude Code
  • Every service restarts itself and reports its health, and problems raise an alert.
  • Sign-in decides what each person sees: viewers get a read-only view, and only the admin has controls.
Section B · Change rate

135 change requests, by day

Section C · Change log

How the system changed, day by day

Oct 1CR-0001 – 0016
Foundation
  • CR-0001Code repository, change records, a verify step and a read-only preview
  • CR-0015Profit Taking Protocol added to the strategy engine
  • CR-0002–05Faster dashboard refresh; Whale Watch markers
  • CR-0016Whale Watch layout restored alongside the new protocol

From here on, every change goes through a branch, a written record and a release note. That paper trail is what made the fast pace below safe.

Oct 2–3CR-0017 – 0040
Data correctness
  • CR-0018Price index clock alignment; one shared forecast evaluation
  • CR-0022Independent BTC price proxies from three exchanges
  • CR-0035Private GitHub repository; Claude takes over development from Codex
  • CR-0037Window timing follows market time, not the computer's clock
  • CR-0039Depth-weighted proxy prices refreshed every second

The bot trades 15-minute windows, so time is part of the data. A clock running seconds slow skews results, so the logic moved to market time.

Oct 4CR-0041 – 0073
Data lifecycle and CI
  • CR-0041Faster Whale Watch queries through a database index
  • CR-0043Memory-leak audit
  • CR-0062Data retention: 7 days in detail, older data compressed into an archive
  • CR-0067Automated checks on every change, and one shared, test-gated release script
  • CR-0068–70Dependency security audits and code linting made mandatory
  • CR-0073Automatic dependency updates; production releases need green checks

Raw price ticks were nearly all of a database growing about 1 GB a day. Retention keeps its size steady, which made a small cloud server practical.

Oct 5CR-0074 – 0082
Test pyramid
  • CR-0075Component tests for the dashboard
  • CR-0076Full browser tests; coverage targets that only go up
  • CR-0077Replay harness pins every strategy decision on recorded days
  • CR-0078One-command release

The replay harness is the key safety net. Any change that alters a trading decision fails the build unless the change is intended and explained.

Oct 6CR-0083 – 0104
Cloud migration
  • CR-0091Read-only web access for viewers; controls for the admin only
  • CR-0095–96Production moved to a dedicated cloud server with a few minutes' switchover
  • CR-0097Bot health alerts and scheduled backups
  • CR-0098Releases deploy automatically from the code repository
  • CR-0101The main branch moves only after a change's checks pass
  • CR-0102–04Locked dependency versions, website health alerts, architecture doc

The data moved in two steps, a full copy and then the last few minutes, so the switch was quick and nothing was lost.

Oct 7CR-0105 – 0134
Identity and hardening
  • CR-0106More health alerts, an operations runbook and an alert test
  • CR-0107–10New sign-in system: shipped switched off, then turned on, then moved to production
  • CR-0112Abuse protection on the data API
  • CR-0116Safer automatic server updates
  • CR-0123Viewers share the same data responses, which lightens the server's load
  • CR-0124Terms, privacy policy and disclaimer, with tracked acceptance
  • CR-0127–29Version numbers, leaner build pipeline, overload guards
  • CR-0130Claude Code skills, review agents and safety hooks

The busiest day. Viewers got their own accounts, and the server got the safeguards a public site needs.

Oct 8CR-0135
Public identity
  • CR-0135The site moves to btcmm.app; old links redirect with their path kept
  • CR-0135Sign-in moved to the new domain with every account kept
  • OpsContact email on the new domain

Sign-in paused for a few minutes during the move, and the bot never stopped.

Section D · Review against architecture pillars

What each pillar looks like now

PillarOctober 1October 8Key CRs
ReliabilityOne laptop; the site stops when the laptop doesDedicated cloud server, services that restart themselves, scheduled backups0096 0097 0116
SecurityOne shared gate in front of the whole sitePer-user accounts, sign-in checked on every data request, read-only by default, secrets kept in a managed vault0091 0109 0110 0125
Operational excellenceManual releases and restartsChecks on every change, automatic deploys, a written runbook, health alerts0067 0098 0101 0106
QualityA single verify script501 tests across three layers, a replay harness for every strategy decision, coverage that only goes up0075 0076 0077
PerformanceDatabase growing about 1 GB a dayData retention with archive, indexed queries, shared responses, polling pauses in hidden tabs0041 0062 0116 0123
CostTied to a personal machineA small, right-sized server and free tiers elsewhere; build pipeline usage cut by about 70%0096 0128
Section E · Ground rules

Rules that held all week

Paper only

No real money moves

The bot simulates trades against live market data. It has no path to place real orders.

Recorded changes

Every change has a record

Each CR has its own branch, written record and release note, and passes the checks before it ships. Each one can be rolled back.

Calm releases

The bot keeps running

Dashboard updates ship on their own. The bot restarts only when its code changes, and only just after a 15-minute window ends.

Section F · Beyond

How this would scale

The current system is sized for a paper bot and a few dozen viewers. Each step below starts on a measurable trigger, not a date. The cheapest fix that removes the next bottleneck comes first, and the hard requirements for real money come last.

Stage 0 · today

One server, done well

Tens of viewers · paper only

  • One small cloud server runs the bot and the dashboard
  • Embedded database with retention and weekly backups
  • Managed sign-in, edge network, health alerts
  • Tested, automatic deploys
Recovery point
7 days
Recovery time
~30 min
Monthly cost
lowest
Stage 1 · harden

Separate and protect

>100 active viewers, or anyone outside the invite list

  • Bot on its own instance, isolated from viewer load
  • Continuous database backup to object storage
  • Shared API snapshots cached at the edge for 1–2 s
  • Infrastructure as code, a staging copy, blue/green dashboard deploys
  • Central logs and a latency target (SLO) with alerts
Recovery point
minutes
Recovery time
~10 min
Monthly cost
~2–4×
Stage 2 · scale out

Stateless and pushed

>1,000 concurrent viewers, or API p95 over target

  • Stateless API containers that autoscale behind a load balancer
  • Live updates pushed over streams instead of 1-second polling
  • Managed Postgres across two zones, plus a read replica
  • Ticks archived as columnar files, queried on demand
  • Two availability zones; the bot keeps a warm standby
Recovery point
<1 min
Recovery time
<5 min
Monthly cost
~20–40×
Stage 3 · real money

Isolate the trading path

Any live order path, or users' own exchange keys

  • Trading engine in its own account and network
  • Pre-trade risk limits, position caps and a kill switch
  • Immutable order ledger and daily reconciliation
  • Per-user keys in a hardware-backed vault
  • Second-region recovery, on-call rota, outside security test, legal review
Recovery point
0 orders
Recovery time
<15 min
Monthly cost
people-led

Recovery point is how much recent data a failure can lose. Recovery time is how long until the site is back. Costs are relative to today.

Stage 2 target architecture

To be
Users thousands of tabs Edge network cache 1–2 s snapshots · WAF · rate limits sign-in token check before origin Sign-in service users, roles, sessions PRIVATE NETWORK · TWO AVAILABILITY ZONES Load balancer API containers × N stateless · autoscale on CPU and latency Pub/sub stream push to viewers Bot engine + warm standby Managed Postgres · primary + read replica events, state, 1-minute rollups; point-in-time restore Object storage tick archive, columnar Pipeline infrastructure as code · tests · replay harness staging → blue/green → automatic rollback Observability central logs · metrics · traces SLOs with error budgets · on-call alerts Secrets and identity vault-held keys · short-lived deploy credentials least-privilege roles per service Market data upstream only the bot calls the exchanges; viewer traffic never reaches them
What breaks firstWhyEarly warningFix (stage)
MemoryThe bot and the dashboard share one small serverMemory alertsRun the bot on its own server (1)
Polling fan-outEach open tab asks for fresh data several times a second, so load grows with every viewerRate-limit hits, server CPUEdge-cached snapshots (1), push streams (2)
Chart renderingCharts are built on the server, so CPU grows with viewersSlow chart requestsCache at the edge (1), render in the browser (2)
Single serverOne server in one location; a restore takes a whileServer health checksContinuous backup (1), two zones and a standby (2)
Embedded databaseOne writer suits one bot; many bots or tenants need concurrent writesWrite waitsManaged Postgres (2)
Plan tiersFree tiers cap users and protection rulesUser-count alertsUpgrade as traffic justifies (1–2)
Principle

Scale reads, not the bot

Viewers only read. Caching and pushing shared snapshots handle almost all growth, and the single bot never sees viewer traffic.

Principle

Keep the safety nets

The replay harness, checks before main and change records carry into every stage, so a bigger system still can't ship an untested trading change.

Principle

Money changes the rules

Stages 1 and 2 are about uptime and cost. Stage 3 adds isolation, audit and legal duties, and it isn't worth starting without a reason to trade live.