From f783cfaf808299f7d9d53bafb6bdb3dbc6dff2b0 Mon Sep 17 00:00:00 2001 From: Davide Grilli Date: Tue, 21 Jul 2026 10:27:12 +0200 Subject: [PATCH] Update CLAUDE.md with real commands and known gaps Records the MVP build as code-complete and unit-tested, documents the real install/run/test commands now that the project is scaffolded, and lists known gaps (scheduler restart resume, payout retry, RBF fallback, missing history endpoints, deployment, admin auth, rate limiting) to address before treating this as production-ready. Co-Authored-By: Claude Sonnet 5 --- CLAUDE.md | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/CLAUDE.md b/CLAUDE.md index 1e3346e..c58fd9e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,10 +8,32 @@ The user communicates in Italian in chat — reply to them in Italian. Everythin ## Project status -This repository is at the **specification stage, not yet implemented**: it currently contains only [flowchart.mmd](flowchart.mmd), which is the source of truth for the project and describes the entire application flow. The tech stack is decided (see below) but no code, build system, or lint/test commands exist yet — once the project is scaffolded, this section must be updated with real commands (install, run, lint, test — including how to run a single test). +All 10 build-order stages from `/home/davide/.claude/plans/scalable-mixing-sloth.md` are code-complete and unit-tested (49 tests green): project skeleton, DB schema + Alembic migrations, auth, HD wallet derivation, Electrum client, deposit detection, bet flow, round/draw engine, payout, withdrawal, RBF fee-bump, admin config + audit log. + +Real-money verification on mainnet, done so far: registration + address derivation, deposit crediting (1-conf), a real 10 PLM bet (broadcast, confirmed, change credited back), and a full round cycle — close → draw (real block hash) → payout (70/30 split, exact sat math verified against the broadcast tx) → confirmation → round closed → next round auto-opened. Withdrawal and the RBF bump path are unit-tested but have never been exercised against a live broadcast. See "Known gaps" below before treating this as production-ready. Before writing code, always read [flowchart.mmd](flowchart.mmd) in full: every node in the diagram corresponds to a behavior that must be implemented exactly as described, including the labels on the edges (conditions, retries, loops). +## Commands + +```bash +source .venv/bin/activate # venv already created at .venv/ +pip install -e ".[dev]" # install/update deps + +alembic upgrade head # apply DB migrations +alembic revision --autogenerate -m "message" # generate a new migration after editing app/db/models.py + +PYTHONPATH=. python scripts/generate_master_key.py # one-time: create+encrypt the server's master xprv (requires XPRV_ENCRYPTION_KEY in .env) + +uvicorn app.main:app --reload --port 8123 # run the dev server + +python -m pytest # run all tests +python -m pytest tests/unit/test_hd.py # run one test file +python -m pytest tests/unit/test_hd.py::test_derivation_is_deterministic # run a single test +``` + +`.env` (gitignored) holds real secrets for local dev; `.env.example` documents the required keys and how to generate them. + ## Tech stack (MVP) - **Backend language**: Python. @@ -65,3 +87,17 @@ These choices were made explicitly during design (not derivable from reading a s - The user's personal deposit address always doubles as the winnings-receiving address: there is no separate "winner address". - 1 confirmation is the chosen threshold for all tx types (deposits, bets, payouts, withdrawals): don't introduce different thresholds (e.g. 3 or 6 confirmations) without an explicit decision. - The draw algorithm (node R) is deliberately simple and should be treated as a replaceable/pluggable component, not the final design — don't architect around its current implementation. + +## Known gaps / TODO + +Not blockers for reading the code, but must be addressed before this is production-ready: + +- **Scheduler doesn't resume mid-flight rounds after a restart.** `rounds/scheduler.py`'s `_tick()` only acts on rounds with `status == "open"`. If the process restarts while a round is `closing`/`drawing`/`paying_out`, it's permanently stuck — nothing re-enters `_wait_for_next_block` or retries `_trigger_payout`. Needs a startup routine that inspects in-progress rounds and resumes (or a periodic "unstick" check) before this can run unattended. +- **RBF bump only handles one case**: a single change output, paying back to the tx's own sender address, large enough to absorb the fee increase. No additional-input selection fallback — an exact-amount tx (no change) or a change output too small to absorb the bump raises `RbfError` and needs manual operator intervention. Documented in `tx/broadcast.py`. +- **Payout retry**: if `_trigger_payout` fails (e.g. insufficient pool UTXOs, Electrum disconnected), it just logs and returns — the round stays stuck in `paying_out` with no automatic retry. +- **Withdrawal and RBF bump have never been exercised against a live broadcast** — only deposit and bet flow are verified end-to-end with real PLM as of this commit. +- **No user-facing history endpoints** (list my bets / withdrawals / past rounds) — only `/users/me` (balance) exists. +- **No deployment setup**: no Dockerfile, process manager, or reconnect/supervision beyond the in-process asyncio tasks. Currently only run manually via `uvicorn` in a dev venv. +- **Admin auth is a single shared bearer token** (`ADMIN_TOKEN`, `X-Admin-Token` header) — no per-admin identity or audit trail of who changed config. +- **No rate limiting / abuse protection** on any endpoint (register, bet, withdrawal). +- No automated integration tests against a live Electrum connection — all live-network verification so far has been manual (ad hoc scripts + real mainnet transactions), not part of the `pytest` suite.