Simulators
Pull request UI
The pull request UI shows the simulator’s repository the way GitHub draws it, so you can watch what your automation does and act as a person would. Open $RYSTIC_URL/_rystic/ui in a browser: the Repository card draws the Pull requests and Issues lists and a pull request’s Conversation, Commits, Checks and Files changed tabs, and redraws as your calls arrive. Every action in it goes through the simulator’s own REST API, so a write from the UI and a write from your code leave the same trace:
curl -s -o /dev/null -w '%{http_code}\n' "$RYSTIC_URL/_rystic/ui"
# -> 200
curl -s -X POST "$RYSTIC_URL/repos/tb-owner/tb-repo/issues/41/comments" -H 'Authorization: Bearer ghp_anything' -H 'X-Rystic-Actor: tb-maintainer' -d '{"body":"Looks right to me"}' | jq -c '{id, user: .user.login}'
# -> {"id":6100001,"user":"tb-maintainer"}
curl -s "$RYSTIC_URL/_rystic/calls" | jq -c '.calls[] | {actor, method, status}'
# -> {"actor":"tb-maintainer","method":"POST","status":201}
curl -s -X POST "$RYSTIC_URL/repos/tb-owner/tb-repo/pulls/41/reviews" -H 'Authorization: Bearer ghp_anything' -H 'X-Rystic-Actor: tb-maintainer' -d '{"event":"APPROVE"}' | jq -c '{state}'
# -> {"state":"APPROVED"}
curl -s "$RYSTIC_URL/_rystic/egress" | jq -c '{total}'
# -> {"total":2}
View as anyone
The button at the top right picks the seeded user the view acts as, with that user’s standing on the repository beside it. The Actors and calls card lists every seeded user and alias with its standing, and the live request log.
Act as them
The view’s writes go through the simulator’s own API (REST, and GraphQL for draft and ready), with X-Rystic-Actor set to the chosen user. Its actions include comments, reviews, line comments from the + in a diff, replies, reactions, review requests, merges, Update branch, close and reopen, title edits, locks and new issues. The simulator applies its permission rules, GET /_rystic/calls attributes the write and a refused write shows the simulator’s own status and message. Writes are never retried.
Labels, assignees and milestones are drawn read-only: change them through the REST routes (.../labels, .../assignees and PATCH .../issues/{n}).
Checks
Nothing runs CI in the UI, so the Checks tab carries a Rystic control that sets a check run’s status and conclusion, rerequests it or creates one on the head sha. Annotations render on their lines in Files changed. The checks a push starts through Workflows and CI runs appear there too.
Webhook events
Webhook events lists what the simulator rendered into GET /_rystic/egress, newest first, each with its payload: the deliveries GitHub would have made.
What it contacts
Links never open and images load only when clicked, and the page contacts nothing but the simulator.
Refreshing
Switching users or repositories closes open edits, menus and the review panel and discards pending responses. Resetting, loading a scenario or detecting a gap in the event feed also clears drafts and returns to the pull request list, and responses from the previous scenario cannot change the new one.
The imported scenario reads about 90 MB per refresh. Writes and control events refresh the view, spaced by twice the last read’s time. A failed read shows an error with a Retry button and retries automatically with bounded backoff.