Solskannah
Potentially terribull
Vote to see the stats!
Memecoin whale group hunter (Pump Clusters)
Finds pump.fun wallets that ride winners, links wallets that enter together into crews, tracks
their next buys and paper-trades the signals. Read docs/brief.md (the build brief) and
docs/decisions.md (dated decisions) before changing anything.
Constraints you must not break
- Rate limit.
swap-api.pump.fun(trade feed, candles) cuts off at about 100 requests a minute per IP with a 60-second penalty. It is paced at 1.5 requests a second inpc/api.py. Never run two coin-scan processes at once and never raise that rate. - Window on real trade times. pump.fun's
updatedAtcan be an indexing date. The 60-day window is enforced on first-buy times inanalyze.filter_recent. Keep it that way. - Code owns the math. Jev (TypeSafe) only answers typed questions about text or
pre-bucketed facts, one request per item, all questions batched. See
pc/enrich.py. - Read-only. The app never touches a wallet and places no trades. Paper trades are rows in a table.
- No secrets in git. Keys come from the environment.
.envis gitignored. No wallet private key exists anywhere in this project. - Keep the reference. Commit
data/result.jsonfrom 2026-10-02 as a fixture and never overwrite it. New builds are new snapshots. - One job at a time. Scans, builds and traces share rate limits and cache files.
- Unreliable data never counts (user, 9 Oct). Data a known bug affected is quarantined in
paper/record.py. It stays out of every result, figure and backtest, because bad or incomplete data skews backtesting. Data the bug didn't touch is kept: quarantine by the records and fields affected, never by deleting whole periods. A finding that may rest on quarantined data is flagged in Linear as Urgent and re-checked before anyone relies on it.
In this repo the reference fixture is reference/result-2026-10-02.json; the working copy the
engine protects is data/pc/result.reference.json. Every request to pump.fun, from any module,
takes its turn in the one per-host pacer in pc/api.py.
Working rules
- Ask Hans before creating anything that costs money or lives in an account (GitHub, Supabase,
Vercel, Linear teams), before changing Windows power, sleep or startup settings, before
stopping or restarting the running tracker, before deleting or moving anything under
data/, and before changing a rule inpc/config.pyor the saved settings. - One job at a time: the engine's job runner enforces it. Do not start a scan, build or trace from a second process while the engine is running.
- Plain commit messages, one change per commit.
- Work is tracked in Linear. Update the issue when a task starts and when it ends.
- Move code first, change behaviour second.
- Decisions for Hans are asked as multiple-choice questions (the AskUserQuestion tool), with the recommended option first. Never leave them as a numbered list he has to answer in free text.
Run
python hunter.py # engine + dashboard on http://localhost:8010
python hunter.py --track # same, with the signal tracker on
python -m unittest discover -s tests # all tests, no network
python -m ruff check . # lint (rules in ruff.toml); GitHub Actions runs both
Run both before a commit. When Ruff calls an import unused, check it is not reached by name or set from outside
(_MODULE_SETTINGS in copytrader.py, build.DATA) before removing it; mark such imports # noqa: F401 with the reason.
The tests need no keys and no data folder. tests/fixtures/ holds small records cut from the
reference cache.
Layout
pc/ is vendored from the Cowork build with three hooks; supabase/migrations/ takes one numbered SQL file per change.
Start here
Read docs/handover.md for where the project stands, then docs/decisions.md. Open work is in Linear (team Solana).
Design system
Before any UI work (dashboard.py, ui/, page HTML or CSS, charts) load the solskinn-ui skill; it holds the Solskinn rules.
Never edit the files in docs/design-system/ to make the UI pass. If a value or component is missing, say so and stop.