Simulators
Review-bot scenarios
github-pulls_bot_pr_broken and github-pulls_bot_pr_queue hold a Kalshi market-maker bot and pull requests that break it in known ways. A review agent reaches the bot only as diffs, exactly as it meets any code in a pull request. Load the first, read the working bot from the merged pull request and the one-line break from the open one:
H='Authorization: Bearer ghp_anything'
R="$RYSTIC_URL/repos/tb-owner/tb-repo"
curl -s -X POST "$RYSTIC_URL/_rystic/scenario" -d '{"name":"github-pulls_bot_pr_broken"}' -o /dev/null
curl -s "$R/pulls?state=all" -H "$H" | jq -c '[.[] | {number, state, merged: (.merged_at != null)}]'
# -> [{"number":8,"state":"open","merged":false},{"number":7,"state":"closed","merged":true}]
curl -s "$R/pulls/7/files" -H "$H" | jq -c '[.[] | {filename, additions}]'
# -> [{"filename":"bots/kalshi_mm/bot.py","additions":158}]
curl -s "$R/pulls/7/files" -H "$H" | jq -r '.[0].patch' | head -1
# -> @@ -0,0 +1,158 @@
curl -s "$R/pulls/8/files" -H "$H" | jq -r '.[0].patch' | head -1
# -> @@ -140,7 +140,7 @@ class MarketMaker:
curl -s "$R/check-runs/6508/annotations" -H "$H" | jq -c '[.[] | {path, start_line, annotation_level}]'
# -> [{"path":"bots/kalshi_mm/bot.py","start_line":143,"annotation_level":"failure"}]
Strip the leading + from #7’s patch and you have bot.py; apply #8’s hunk and you have the broken head. #8 carries a red bot-smoke check run that annotates the broken line.
Running the bot
Run either file against a Kalshi simulator. It needs Python’s requests package:
pip install requests
KALSHI_BASE_URL=http://localhost:8081 TICKER=KXDEMO-26-A SESSION_SECONDS=30 python3 bot.py
bot.py rests a bid and an ask behind the touch on one market, re-quotes as the book moves and never crosses. It stops quoting a side once its position reaches MAX_INVENTORY, though a fill can carry it past by up to QUOTE_SIZE. It cancels everything at SESSION_SECONDS (default 30) or on SIGTERM. It reads its settings only from the environment: KALSHI_BASE_URL, TICKER, QUOTE_SIZE, MAX_INVENTORY and the others its docstring lists.
The same files ship as plain text in the release archive: bots/bot.py, bots/variants/*.py and bots/test_bot.py. The container image does not carry them. The scenario’s patches are generated from those files, so the diffs and the plain text cannot disagree.
test_bot.py runs the working bot for 30 seconds against kalshi-twin --scenario tight_book and requires a bid and an ask resting at once, no crossed quote and nothing left resting. It then runs every variant and requires each to fail that. It boots the kalshi-twin that rystic pull installed, or the binary KALSHI_TWIN_BIN names, or uses the simulator already serving at KALSHI_BASE_URL, and loads tight_book before each bot.
The variants
github-pulls_bot_pr_queue holds the same merged bot, then five open pull requests (#11 to #15) that each break it a different way:
| Open pull request | Variant | What breaks | Result on the Kalshi simulator |
|---|---|---|---|
| #8 and #11 | sides_inverted | the buy leg goes out as ask, the sell leg as bid | 400 invalid_order: post only cross |
| #12 | syntax_error | def requote(self) lost its colon | the file does not compile |
| #13 | wrong_endpoint | orders posted to /trade-api/v2/orders | 404 not_found |
| #14 | price_in_cents | "38" where "0.38" was meant | 400 invalid_price |
| #15 | missing_required_field | self_trade_prevention_type dropped from the body | 400 missing_parameters |
Every one of them has its own red check run and line annotation. Use them to test a grader or a review agent: approving any of them means it missed the bug.